HAVING 过滤分组
理解 WHERE vs HAVING 的区别、分组后过滤
HAVING 过滤分组
WHERE 在分组前过滤行,HAVING 在分组后过滤分组。很多人分不清这两个——记住:WHERE 不能跟聚合函数,HAVING 专门跟聚合函数。
学完本章你将: 掌握 HAVING vs WHERE 的区别、按聚合结果筛选。
HAVING 基本用法
sql
-- 查用户数超过 5 的城市
SELECT city, COUNT(*) AS 人数
FROM users
GROUP BY city
HAVING COUNT(*) > 5; -- 过滤分组后的结果
-- ❌ 这样不行:
-- WHERE COUNT(*) > 5 -- WHERE 不能用聚合函数!
WHERE vs HAVING 对比
sql
-- WHERE:过滤原始行(分组前)
-- HAVING:过滤聚合结果(分组后)
SELECT city, AVG(age) AS 平均年龄
FROM users
WHERE age > 0 -- ① 先排除年龄为 0 的脏数据
GROUP BY city
HAVING AVG(age) > 30 -- ② 再筛选平均年龄大于 30 的城市
ORDER BY 平均年龄 DESC; -- ③ 最后排序
WHERE 和 HAVING 都用
sql
-- 北京的 18+ 用户数 > 3 的部门
SELECT department, COUNT(*) AS 人数
FROM users
WHERE city = '北京' AND age >= 18 -- 先筛选行
GROUP BY department
HAVING COUNT(*) > 3 -- 再筛选组
ORDER BY 人数 DESC;
能用 WHERE 就别用 HAVING
WHERE 利用索引更快,HAVING 在分组之后才执行。能把条件放 WHERE 里就放 WHERE:
sql
-- ✅ 好
SELECT city, COUNT(*) FROM users WHERE age > 18 GROUP BY city;
-- ❌ 不好(WHERE 能做到的别交给 HAVING)
SELECT city, COUNT(*) FROM users GROUP BY city HAVING city != '测试';