模块 3 · 第 4 课(共 4)课程中的12/57~8 min
模块课程(4/4)
过滤组:HAVING
一旦您获得了每组的结果(上一课),您通常会想要
仅保留满足条件的组:拥有更多的部门
2人以上,项目平均预算10万以上,用户
至少 10 个订单。要做到这一点 WHERE 还不够。
为什么 WHERE 还不够
WHERE 过滤 表行,before 聚合。所以看不到
COUNT(*) 或 AVG(...) 的结果:到 WHERE 运行时,那些
值尚未计算。
SQL
-- ERROR: COUNT(*) doesn't exist yet when WHERE is evaluated
SELECT department_id, COUNT(*) AS count
FROM employees
WHERE COUNT(*) > 2 -- ❌ doesn't work
GROUP BY department_id;要在聚合后过滤,有一个专用子句:HAVING。
语法
SQL
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM table
GROUP BY grouping_column
HAVING condition_on_aggregate;SQL
-- Departments with more than 2 employees:
SELECT department_id, COUNT(*) AS count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 2;HAVING 与 GROUP BY 的关系就像 WHERE 与 FROM 的关系:相同的想法
(“过滤器”),但在聚合之后应用**分组。
子句的逻辑顺序
为了不再混淆 WHERE 和 HAVING,请记住其中的顺序
SQL 在心里执行它们:
FROM/JOIN— 通过连接源构建起始表。WHERE— 删除您不关心的行。GROUP BY— 将剩余行收集到组中。HAVING— 删除您不关心的组。SELECT— 计算最终列(包括聚合)。ORDER BY/LIMIT— 重新排序和剪切。
重要提示:
- 在
WHERE中你只能使用表列; - 在
HAVING中,您可以使用分组列和聚合。
SQL
-- Classic combo: filter first, group, filter the groups, sort.
SELECT d.name, AVG(e.salary) AS average
FROM employees AS e
JOIN departments AS d ON e.department_id = d.id
WHERE e.hired_on >= '2018-01-01' -- filter rows
GROUP BY d.name
HAVING AVG(e.salary) > 35000 -- filter groups
ORDER BY average DESC;尝试一下
锻炼#sql.m3.l4.e1
尝试:0加载中...
对于每个部门,显示名称 (departments.name) 和员工人数,但仅适用于至少有 2 名员工的部门。每个合格部门两列,一行。
正在加载编辑器...
显示提示
“至少 2”条件在 HAVING 中变为 COUNT(*) >= 2。
3 次尝试后可用的解决方案
复习练习
锻炼#sql.m3.l4.e2
尝试:0加载中...
显示平均工资超过 35000 的部门 (departments.name)。仅考虑从 2018 年起雇用的员工。两列:名称和平均值。按平均降序排序。
正在加载编辑器...
显示提示
WHERE 过滤行(从 2018 年开始雇用的员工),HAVING 过滤组(平均值 > 35000)。
3 次尝试后可用的解决方案