摘要:本教程介绍了 SQL HAVING 子句,该子句允许指定由 GROUP BY 子句汇总的组的条件。
SQL HAVING 子句简介
在前面的教程中,您已经学习了如何使用 GROUP BY 子句将行汇总到组中,并将聚合函数应用到每个组中,如 MIN、MAX、SUM、COUNT、AVG。
若要为组指定条件,请使用 HAVING 子句。
HAVING 子句通常与 SELECT 语句 中的 GROUP BY 子句一起使用。如果不带 GROUP BY 子句使用 HAVING 子句,则 HAVING 子句将表现得类似于 WHERE 子句。
以下说明了 HAVING 子句的语法
SELECT
column1,
column2,
AGGREGATE_FUNCTION (column3)
FROM
table1
GROUP BY
column1,
column2
HAVING
group_condition;
Code language: SQL (Structured Query Language) (sql)
请注意,HAVING 子句紧跟在 GROUP BY 子句之后。
HAVING 与 WHERE
在行由 GROUP BY 子句汇总到组之前,WHERE 子句对各个行应用条件。但是,HAVING 子句在行分组到组之后,对组应用条件。
因此,重要的是要注意 HAVING 子句在 WHERE 子句之后应用,而 WHERE 子句在 GROUP BY 子句之前应用。
SQL HAVING 子句示例
我们将取 示例数据库 中的员工和部门表进行演示。

若要获取经理及其直接下属,请使用 GROUP BY 子句按经理对员工进行分组,并使用 COUNT 函数 计算直接下属。
以下查询说明了这个想法
SELECT
manager_id,
first_name,
last_name,
COUNT(employee_id) direct_reports
FROM
employees
WHERE
manager_id IS NOT NULL
GROUP BY manager_id;
Code language: SQL (Structured Query Language) (sql)

若要查找至少有 5 名直接下属的经理,请将 HAVING 子句添加到如下的查询中
SELECT
manager_id,
first_name,
last_name,
COUNT(employee_id) direct_reports
FROM
employees
WHERE
manager_id IS NOT NULL
GROUP BY manager_id
HAVING direct_reports >= 5;
Code language: SQL (Structured Query Language) (sql)

带 SUM 函数的 SQL HAVING 示例
以下语句计算公司为每个部门支付的薪酬 总和,并且只选择薪酬总和 介于 20000 和 30000 之间的部门。
SELECT
department_id, SUM(salary)
FROM
employees
GROUP BY department_id
HAVING SUM(salary) BETWEEN 20000 AND 30000
ORDER BY SUM(salary);
Code language: SQL (Structured Query Language) (sql)

带 MIN 函数的 SQL HAVING 示例
若要查找拥有最低薪酬大于 10000 的员工的部门,请使用以下查询
SELECT
e.department_id,
department_name,
MIN(salary)
FROM
employees e
INNER JOIN departments d ON d.department_id = e.department_id
GROUP BY
e.department_id
HAVING
MIN(salary) >= 10000
ORDER BY
MIN(salary);
Code language: SQL (Structured Query Language) (sql)

查询的工作原理。
- 首先,使用 GROUP BY 子句按部门对员工进行分组。
- 其次,使用 MIN 函数找出每组的最低薪酬。
- 第三,将条件应用到 HAVING 子句。
带 AVG 函数的 SQL HAVING 子句示例
若要查找员工平均薪酬在 5000 到 7000 之间的部门,请使用以下查询中的 AVG 函数
SELECT
e.department_id,
department_name,
ROUND(AVG(salary), 2)
FROM
employees e
INNER JOIN departments d ON d.department_id = e.department_id
GROUP BY
e.department_id
HAVING
AVG(salary) BETWEEN 5000
AND 7000
ORDER BY
AVG(salary);
Code language: SQL (Structured Query Language) (sql)

在本教程中,您已经学习了如何使用 SQL HAVING 子句将条件应用到组。