PostgreSQL HAVING 用法与实例

本文介绍了在 PostgreSQL 中如何使用 HAVING 子句为分组查询指定过滤条件。

在 PostgreSQL 中, HAVING 子句用于为带有 GROUP BY 子句的分组查询指定过滤条件。

HAVING 看起来与 WHERE 相似,虽然他们都是指定过滤条件,但是他们的区别是: WHERE 子句指定的条件用于过滤表中的行,而 HAVING 子句指定的条件用于过滤分组。

PostgreSQL HAVING 语法

PostgreSQL HAVING 子句必须与 GROUP BY 子句一起使用。 以下是 PostgreSQL HAVING 子句典型的用法:

SELECT column1[, column2, ...], aggregate_function(ci)
FROM table
[WHERE clause]
GROUP BY column1[, column2, ...];
HAVING clause

这里,

  • GROUP BY 子句用于指定用于分组的列或者表达式。
  • HAVING 子句用来过滤 GROUP BY 分组的数据,需要使用逻辑表达式作为条件,其中逻辑表达式中的列名或表达式只能使用分组使用的列,表达式,或者应用于分组列或表达式的聚合函数。
  • 您不能在 HAVING 子句中使用列别名。

PostgreSQL HAVING 子句实例

我们将使用 Sakila 示例数据库 中的表进行演示,请您先在 PostgreSQL 中安装 Sakila 示例数据库

使用带有 count 函数的 PostgreSQL HAVING 子句示例

如果您想从 film 表中查找每个影片评级的影片数量,请使用如下语句:

SELECT rating, count(*)
FROM film
GROUP BY rating
ORDER BY count(*) DESC;
 rating | count
--------+-------
 PG-13  |   223
 NC-17  |   210
 R      |   195
 PG     |   194
 G      |   178
(5 rows)

这个实例返回了所有的影片评级的影片数量。如果您想要查找影片数量大于 200 的影片评级,就要用到 HAVING 子句,如下:

SELECT rating, count(*)
FROM film
GROUP BY rating
HAVING count(*) > 200
ORDER BY count(*) DESC;
 rating | count
--------+-------
 PG-13  |   223
 NC-17  |   210
(2 rows)

使用带有 SUM 函数示例的 PostgreSQL HAVING 子句

如果您想从 payment 表中查找总消费金额在 180 美元以上的客户,请使用以下带有 GROUP BY 子句,HAVING 子句和聚合函数 sum() 的语句:

SELECT customer_id, sum(amount) total
FROM payment
GROUP BY customer_id
HAVING sum(amount) > 180
ORDER BY total DESC;
 customer_id | total
-------------+--------
         526 | 221.55
         148 | 216.54
         144 | 195.58
         178 | 194.61
         137 | 194.61
         459 | 186.62
(6 rows)

本例中,执行的顺序如下:

  1. 首先使用 GROUP BY 子句按照 customer_id 字段对数据进行分组,也就是按照客户分组。
  2. 然后使用聚合函数 sum(amount) 对每组中的所有行的 amount 字段求和,并使用 total 作为列别名。
  3. 然后使用 HAVING 子句指定只有 sum(amount) 大于 180 的行才会被返回。
  4. 最后使用 ORDER BY 子句按照 total 降序排列。

结论

PostgreSQL HAVING 子句用于为带有 GROUP BY 子句的分组查询指定过滤条件。 HAVING 子句需要使用逻辑表达式作为条件,其中逻辑表达式中的列名或表达式只能使用分组使用的列,表达式,或者应用于分组列或表达式的聚合函数。