SQLPathLab
SQL 实战指南 · MySQL 8.0

WHERE 和 HAVING 的真正区别

WHERE 筛选明细行,HAVING 筛选聚合后的分组。

问题与判断方法

WHERE 在 GROUP BY 之前决定哪些明细行参与计算;HAVING 在分组和聚合之后决定保留哪些分组。日期、状态、地区等原始字段条件通常属于 WHERE,订单数或销售额等聚合条件属于 HAVING。

把明细条件放进 HAVING 可能依赖数据库的宽松行为,也会让查询意图模糊。能够提前过滤的数据应优先在 WHERE 中处理,这通常还能减少进入聚合阶段的数据量。

排查时先用 WHERE 得到正确明细,再加入 GROUP BY,最后增加 HAVING。每一步都检查行数或分组数。

示例

示例数据表

表名:orders
orders
departmentamount
Sales 1200
IT 900
Sales 1500
HR 700

优化前 / 不推荐

SELECT department, SUM(amount) AS total FROM orders GROUP BY department HAVING department = 'Sales';

优化前运行结果

result
departmenttotal
Sales 2700

优化后 / 推荐

SELECT department, SUM(amount) AS total FROM orders WHERE department = 'Sales' GROUP BY department;

优化后运行结果

result
departmenttotal
Sales 2700

为什么这样更好:结果相同,但 WHERE 在聚合前表达明细条件;HAVING 应保留给 SUM、COUNT 等分组后条件。

这篇内容是否清楚?