Skip to content

PostgreSQL - HAVING 子句

PostgreSQL 的 HAVING 子句用于过滤 GROUP BY 子句的结果。WHERE 子句在分组 之前 过滤单个行,而 HAVING 子句在聚合执行 之后 过滤整个组。

  • WHERE 子句:根据应用于单个列的条件过滤行。它在 GROUP BY 和聚合函数(如 COUNT()、SUM()、AVG()) 之前 处理。
  • HAVING 子句:根据应用于聚合函数结果的条件过滤组。它在 GROUP BY 子句 之后 处理。

一个简单的经验法则:如果你的条件涉及聚合函数,它就属于 HAVING 子句。否则,为了更好的性能,它应该属于 WHERE 子句。

HAVING 子句必须出现在 GROUP BY 子句之后和 ORDER BY 子句之前。

SELECT
column1,
aggregate_function(column2)
FROM
table_name
WHERE
[row_conditions]
GROUP BY
column1
HAVING
[group_conditions]
ORDER BY
[column | expression];

示例 1:查找平均薪资较高的部门

Section titled “示例 1:查找平均薪资较高的部门”

让我们使用 employees 表来查找所有平均薪资高于 75,000 美元的部门。

-- 员工表示例数据:
-- department | salary
-- --------------+--------
-- Engineering | 90000
-- Engineering | 80000
-- Sales | 70000
-- Sales | 85000
-- HR | 60000
SELECT
department,
AVG(salary) AS average_salary
FROM
employees
GROUP BY
department
HAVING
AVG(salary) > 75000;

此查询首先按部门对员工进行分组,计算每个组的平均薪资,然后 HAVING 子句过滤这些组,只返回平均薪资高于 75,000 美元的部门。

预期结果:

department | average_salary
-------------+----------------
Engineering | 85000.00
Sales | 77500.00
(2 rows)

让我们查找每个类别中的产品数量,但只针对价格超过 20 美元的产品,并且只显示拥有超过 5 个此类产品的类别。

SELECT
category_id,
COUNT(product_id) AS product_count
FROM
products
WHERE
price > 20.00 -- 首先过滤单行
GROUP BY
category_id
HAVING
COUNT(product_id) > 5; -- 计数后过滤组

在此示例中:

  • WHERE 子句首先过滤掉所有价格为 20 美元或更少的产品。
  • GROUP BY 子句然后按类别对剩余产品进行分组。
  • 最后,HAVING 子句过滤这些组,只保留数量大于 5 的组。