GROUP BY 和 HAVING 必须配合使用才能过滤分组结果;单独 HAVING 会报错,因无分组则无“分组后”数据可筛;SELECT 非聚合字段必须出现在 GROUP BY 中,否则触发 ERROR 1055;HAVING 只能引用聚合函数或分组字段,不可用原始行单值字段。
GROUP BY 和 HAVING 必须一起用才能过滤分组后的结果;单独写 HAVING 会报错,因为没有分组就没有“分组后”的数据可筛。
MySQL(及多数标准 SQL)要求:SELECT 列表里的每个非聚合字段,都得出现在 GROUP BY 子句中。否则直接报错 ERROR 1055(在严格模式下)。
SELECT department, COUNT(*) FROM employees GROUP BY department;
SELECT name, department, COUNT(*) FROM employees GROUP BY department; —— name 既没在 GROUP BY 里,也没套聚合函数,数据库不知道该取哪一行的 name。ONLY_FULL_GROUP_BY 模式,这个限制是硬性的;关掉它只是掩盖问题,不是解决问题。HAVING 是对「每组聚合完之后」那行结果做判断,所以条件里可以放心用 COUNT(*)、SUM(amount) 这类,但不能用原始行的单值字段(除非它也在 GROUP BY 里)。
HAVING COUNT(*) > 3、HAVING AVG(salary) >= 12000、HAVING department = 'tech'(因为 department 是分组字段)HAVING salary > 10000 —— salary 不是分组字段,也不是聚合结果,这行根本不存在于 HAVING 执行时的上下文中。WHERE salary > 10000 放在 GROUP BY 前面,而不是硬塞进 HAVING。SQL 实际执行顺序是:FROM → WHERE → GROUP BY → 聚合计算 → HAVING → SELECT → ORDER BY。这个顺序决定了什么能做什么不能做。
HAVING COUNT(*) > 100,数据库必须先把所有组的计数全算出来,再一个个比。WHERE order_date >= '2025-01-01' 缩小范围;GROUP BY customer_id;HAVING SUM(amount) > 5000 AND COUNT(*) >= 3。最容易被忽略的是:HAVING 条件里写的别名(比如 AS total),在某些数据库(如 PostgreSQL)里可以直接用,但在 MySQL 8.0 之前不支持——得重复写 SUM(amount) > 5000,不能写 total > 5000。别名可用性取决于具体版本和 SQL 模式,别默认它一定行。