SQL分组后筛选数据_HAVING条件使用技巧

3次阅读

SQL分组后筛选数据_HAVING条件使用技巧

分组后筛选数据,必须用 HAVING,不能用 WHERE —— 因为 WHERE 在分组前执行,而 HAVING 作用于分组结果(即聚合后的数据)。

HAVING 必须跟在 GROUP BY 后面

语法顺序不能错:select → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT。如果没写 GROUP BY,单独用 HAVING 会报错(除非数据库支持扩展语法,如 mysql 5.7 以前允许,但不推荐)。

  • ✅ 正确:GROUP BY dept_id HAVING count(*) > 1
  • ❌ 错误:HAVING COUNT(*) > 1(无 GROUP BY)
  • ⚠️ 注意:WHERE 中不能出现聚合函数,如 WHERE COUNT(*) > 1 是非法的

HAVING 可以使用 SELECT 中的别名(部分数据库支持)

MySQL、postgresql 等支持在 HAVING 中直接引用列别名;SQL Server 和 oracle 则通常要求写完整表达式。

  • MySQL 写法(可读性好):SELECT dept_id, COUNT(*) AS cnt FROM emp GROUP BY dept_id HAVING cnt > 5
  • 兼容写法(通用):HAVING COUNT(*) > 5HAVING COUNT(emp_id) > 5

组合多个条件时,优先用 HAVING 过滤聚合结果

当需要同时满足“人数大于 3”且“平均薪资高于 8000”时,WHERE 无法完成,必须 HAVING:

  • GROUP BY dept_id HAVING COUNT(*) > 3 AND AVG(salary) >= 8000
  • 注意:AVG(salary) 是每组计算出的值,WHERE 拿不到这个结果
  • 若还想排除 NULL 薪资,可在聚合函数中加条件:AVG(CASE WHEN salary IS NOT NULL THEN salary END),再在 HAVING 中判断

性能提示:先用 WHERE 减少数据量,再 GROUP BY + HAVING

HAVING 是对分组结果筛选,不减少中间计算量。想提升效率,应尽量把能提前过滤的条件放在 WHERE:

  • 比如查“2023 年入职且部门人数超 5 人”的部门:
    WHERE hire_date >= '2023-01-01' GROUP BY dept_id HAVING COUNT(*) > 5
  • 避免写成:GROUP BY dept_id HAVING COUNT(*) > 5 AND MAX(hire_date) >= '2023-01-01'(低效,全表分组后再判断)
text=ZqhQzanResources