2.7. 汇总函数

与大多数其他关系数据库产品一样,PostgreSQL 支持聚合函数。聚合函数从多个 Importing 行计算单个结果。例如,存在用于在一组行上计算countsumavg(平均值),max(最大值)和min(最小值)的聚合。

举例来说,我们可以在任何地方找到最高的低温读数:

SELECT max(temp_lo) FROM weather;
max
-----
  46
(1 row)

如果我们想知道阅读所在的城市,可以尝试:

SELECT city FROM weather WHERE temp_lo = max(temp_lo);     WRONG

但这将不起作用,因为不能在WHERE子句中使用聚合max。 (之所以存在此限制,是因为WHERE子句确定要在聚合计算中包括哪些行;因此显然必须在计算聚合函数之前对其进行评估.)但是,在通常情况下,可以重新查询以实现所需结果,这里使用* subquery *:

SELECT city FROM weather
    WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
city
---------------
 San Francisco
(1 row)

这是可以的,因为子查询是一个独立的计算,可以独立计算外部查询中发生的事情自己的聚合。

汇总与GROUP BY子句结合使用也非常有用。例如,我们可以通过以下方法获得每个城市观测到的最高低温:

SELECT city, max(temp_lo)
    FROM weather
    GROUP BY city;
city      | max
---------------+-----
 Hayward       |  37
 San Francisco |  46
(2 rows)

这样我们每个城市就有一个输出行。每个汇总结果都是在与该城市匹配的表行上计算的。我们可以使用HAVING过滤这些分组的行:

SELECT city, max(temp_lo)
    FROM weather
    GROUP BY city
    HAVING max(temp_lo) < 40;
city   | max
---------+-----
 Hayward |  37
(1 row)

这仅对所有temp_lo值均低于 40 的城市提供了相同的结果。最后,如果我们只关心名称以“ S”开头的城市,则可以这样做:

SELECT city, max(temp_lo)
    FROM weather
    WHERE city LIKE 'S%'            -- (1)
    GROUP BY city
    HAVING max(temp_lo) < 40;
  • (((1)) LIKE运算符进行模式匹配,并在Section 9.7中进行了说明。

了解聚合与 SQL 的WHEREHAVING子句之间的交互非常重要。 WHEREHAVING之间的根本区别是:WHERE在计算组和聚合之前选择 Importing 行(因此,它控制哪些行进入聚合计算),而HAVING在计算组和聚合之后选择 Importing 行。因此,WHERE子句不能包含聚合函数。尝试使用聚合来确定哪些行将被 Importing 聚合是没有意义的。另一方面,HAVING子句始终包含聚合函数。 (严格来说,您可以编写不使用聚合的HAVING子句,但是它很少有用.在WHERE阶段可以更有效地使用相同的条件.)

在前面的示例中,我们可以在WHERE中应用城市名称限制,因为它不需要聚合。这比将限制添加到HAVING更为有效,因为我们避免对未通过WHERE检查的所有行进行分组和汇总计算。