Skip to content
  • PostgreSQL HAVING 用法与实例 ​

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

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

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

    PostgreSQL HAVING 语法 ​

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

    sql
    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表中查找每个影片评级的影片数量,请使用如下语句:

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

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

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

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

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

    sql
    SELECT customer_id, sum(amount) total
    FROM payment
    GROUP BY customer_id
    HAVING sum(amount) > 180
    ORDER BY total DESC;
    bash
     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 子句需要使用逻辑表达式作为条件,其中逻辑表达式中的列名或表达式只能使用分组使用的列,表达式,或者应用于分组列或表达式的聚合函数。