WHERE vs HAVING
2026-02-23 本文已影响0人
_浅墨_
Q: 某网站的数据库有一个成绩表 myscore,希望找出成绩表中平均得分小于 90 的所有试卷。
🧠 核心区别:WHERE 和 HAVING 过滤的对象不同
WHERE → 过滤的是【行】,在分组前执行,不能用聚合函数
HAVING → 过滤的是【组】,在分组后执行,专门配合聚合函数
用一句话记住:聚合函数(avg、sum、count...)的条件,必须用 HAVING,不能用 WHERE。
📊 执行顺序图解
myscore 原始数据
┌──────────┬────────┬───────┐
│ paper_id │ stu_id │ score │
├──────────┼────────┼───────┤
│ 1 │ 101 │ 85 │
│ 1 │ 102 │ 92 │
│ 2 │ 101 │ 78 │
│ 2 │ 102 │ 88 │
│ 3 │ 101 │ 95 │
│ 3 │ 102 │ 97 │
└──────────┴────────┴───────┘
↓ GROUP BY paper_id(先分组)
┌──────────┬──────────────┐
│ paper_id │ avg(score) │
├──────────┼──────────────┤
│ 1 │ 88.5 │ ← < 90 ✅
│ 2 │ 83.0 │ ← < 90 ✅
│ 3 │ 96.0 │ ← ≥ 90 ❌
└──────────┴──────────────┘
↓ HAVING avg(score) < 90(再过滤组)
┌──────────┐
│ paper_id │
├──────────┤
│ 1 │
│ 2 │
└──────────┘
💡 SQL 执行顺序(必背)
SELECT paper_id -- ⑤ 最后决定输出哪些列
FROM myscore -- ① 先确定数据来源
WHERE ... -- ② 过滤行(不能用聚合函数)
GROUP BY paper_id -- ③ 分组
HAVING avg(score) < 90 -- ④ 过滤组(可以用聚合函数)
ORDER BY ... -- ⑥ 排序
LIMIT ... -- ⑦ 限制条数
💡 记忆口诀:
WHERE 是保安,进门前检查每个人(行)
HAVING 是裁判,分组后筛选每支队伍(组)
聚合函数是统计结果,保安看不懂,只有裁判才能用