WHERE 在执行分组和聚合之前过滤行,即确定哪些记录将进入分组/聚合。HAVING 在应用聚合函数后过滤分组。
示例:
-- 获取总薪资超过 50000 的部门,排除已离职员工 SELECT department, SUM(salary) as total FROM employees WHERE status = 'active' GROUP BY department HAVING SUM(salary) > 50000;
这里:
可以在 WHERE 中使用聚合函数吗?
错误:试图写 WHERE SUM(amount) > 100,但这是不可以的 — 聚合函数只能在 HAVING 中使用。
示例(错误):
SELECT customer_id, SUM(amount) FROM orders WHERE SUM(amount) > 100 GROUP BY customer_id -- 错误:在 WHERE 中错误使用 SUM()
正确:
SELECT customer_id, SUM(amount) FROM orders GROUP BY customer_id HAVING SUM(amount) > 100;
故事
CRM 开发。在 WHERE 中尝试通过 COUNT(order_id) > 5 来过滤订单数量 >5 的客户,查询无法执行。结果:由于不能在 WHERE 中使用 COUNT,客户数量不正确。
故事
商业分析。在 WHERE 中筛选不活跃商品时使用了 HAVING。结果:导致了“空”组的聚合和缓慢的 SQL。通过将状态筛选移至 WHERE 进行修正。
故事
复杂报告。在没有 GROUP BY 的情况下使用 HAVING 来过滤单独行。在某些数据库中会导致错误,在其他数据库中会导致不明确的行为。结论:HAVING 必须在分组之后,并用于聚合条件。