技术与生活 / 一篇记录
分组查询的条件应该放在哪一层?
WHERE 过滤原始记录,HAVING 过滤分组后的聚合结果。
查询可以先从原始行里排除不符合条件的数据,再对剩余数据分组,最后筛选聚合结果。理解这两个过滤阶段,比死记 WHERE 和 HAVING 的名字更有效。
操作与观察
查询示例以 SQLite 为例;notes 为测试表,包含 id、title、score、category、created_at 字段。
SELECT category, COUNT(*) AS n FROM notes GROUP BY category HAVING COUNT(*) > 1;
用一组只有一条记录的分类检查它是否被排除。
对同一组测试数据分别修改原始条件与聚合阈值,观察计数变化。非分组列的选择规则在不同数据库中有差异,写法应尽量明确。
同一分类存在多条记录时,聚合结果只保留分组维度与聚合值。想展示某条具体记录的标题,需要另行定义选择规则,不能指望数据库替你挑出“最合适”的那一条。
别遗漏这条边界
聚合条件放错阶段会改变含义或直接报错。
参考:SQL 文档。