HAVING用于对GROUP BY分组后的结果进行筛选,作用于聚合数据,不能替代WHERE;WHERE在分组前执行且无法使用COUNT()等聚合函数,而HAVING紧跟GROUP BY后,支持聚合条件过滤。
在 MySQL 中,HAVING 用于对 GROUP BY 分组后的结果 进行条件筛选,它作用于聚合后的数据,不能替代 WHERE(WHERE 是在分组前过滤原始行)。
WHERE 在 GROUP BY 之前执行,无法访问聚合函数(如 COUNT()、SUM()、AVG())的结果。比如你想查“订单数超过 5 的客户”,COUNT(*) 是分组后才有的值,WHERE 无法使用它。
错误写法:
SELECT customer_id, COUNT(*) FROM orders WHERE COUNT(*) > 5 GROUP BY customer_id;
会报错:WHERE 不允许使用聚合函数。
HAVING 必须紧跟在 GROUP BY 之后,语法结构为:
SELECT 列名, 聚合函数
FROM 表名
GROUP BY 分组列
HAVING 过滤条件;
例如,查下单次数 ≥ 3 的客户及其订单数:
SELECT customer_id, COUNT(*) AS order_count
FROM orders
GROUP BY customer_id
HAVING COUNT(*) >= 3;
✔️ 筛选满足聚合条件的分组
✔️ 结合别名简化 HAVING 条件(MySQL 支持)
可以给聚合结果起别名,在 HAVING 中直接引用(注意:标准 SQL 不保证支持,但 MySQL 允许):
SELECT department, AVG(salary) AS avg_sal
FROM employees
GROUP BY department
HAVING avg_sal > 8000;
完整执行顺序是:
WHERE → GROUP BY → HAVING → ORDER BY → LIMIT
这意味着:
典型组合示例:
SELECT customer_id, COUNT(*) AS paid_orders
FROM orders
WHERE status = 'paid' -- 先筛出已支付的原始订单
GROUP BY customer_id
HAVING COUNT(*) >= 2; -- 再筛出至少 2 笔已支付订单的客户