HAVING 子句用于对 SELECT 查询的汇总结果进行过滤。与 WHERE 子句在分组前过滤单条记录不同,HAVING 是在数据分组及聚合计算完成后,对“组”级别的数据进行筛选。核心特性
聚合依赖:主要用于检查聚合函数(如
COUNT()、SUM()、AVG()、MIN()、MAX())的结果。分组配合:通常与
GROUP BY 子句结合使用。支持子查询:
HAVING 条件中可以嵌入标量子查询,实现动态过滤。HAVING 与 WHERE 对比
特性 | WHERE 子句 | HAVING 子句 |
执行阶段 | 在分组前( GROUP BY 之前)执行 | 在分组后( GROUP BY 之后)执行 |
作用对象 | 原始表中的每一行记录 | 聚合后的每一个分组(Group) |
支持函数 | 不支持聚合函数 | 专门处理聚合函数 |
代码示例
基础用法:筛选特定规模的分组
统计各类别下的记录数,并仅保留记录数超过 1 条的类别:
SELECT category, COUNT(*) AS cntFROM t1GROUP BY categoryHAVING cnt > 1;
结合标量子查询
HAVING 子句可以根据其他查询返回的单一数值进行过滤。示例 1:静态标量子查询对比
-- 筛选记录数大于子查询指定值(此处为 1)的分组SELECT category, COUNT(*) AS cntFROM t1GROUP BY categoryHAVING COUNT(*) > (SELECT 1);
示例 2:使用聚合函数子查询实现动态过滤
-- 查找类别编号(或数值)大于全局平均类别的分组SELECT category, COUNT(*) AS cntFROM t1GROUP BY categoryHAVING category > (SELECT avg(category) from t1);
结合标量子查询
-- HAVING 子句中使用标量子查询SELECT category, COUNT(*) AS cntFROM t1GROUP BY categoryHAVING COUNT(*) > (SELECT 1);-- 使用聚合函数作为子查询SELECT category, COUNT(*) AS cntFROM t1GROUP BY categoryHAVING category > (SELECT avg(category) from t1);
优化建议与注意事项
性能原则:如果过滤条件不涉及聚合函数(例如
WHERE status = 'Active'),请务必将其写在 WHERE 子句中。这样可以在分组计算前排除无关数据,显著提升查询效率。别名引用:
HAVING 可以直接引用 SELECT 列表中的列别名(如示例中的 cnt),这增加了代码的可读性。