与大多数其他关系数据库产品一样,PostgreSQL支持聚合函数。聚合函数从多个输入行计算单个结果。例如,有聚合来计算一组行的count、sum、avg(平均值)、max(最大值)和min(最小值)。
例如,我们可以在任何地方找到最高的低温读数:
从天气中选择最大值(temp_lo);
最大限度
46
(1 行)
如果我们想知道读取发生在哪个城市(或多个城市),我们可以尝试:
从天气中选择城市 temp_lo = max(temp_lo); 错误的
但这不起作用,因为该子句max中不能使用聚合。WHERE(存在此限制是因为该WHERE子句确定了哪些行将包含在聚合计算中;因此显然必须在计算聚合函数之前对其进行评估。)但是,通常情况下,可以重述查询以实现所需的结果,在这里使用子查询:
从天气中选择城市
WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
城市
San Francisco
(1 行)
这没关系,因为子查询是一个独立的计算,它计算自己的聚合与外部查询中发生的事情分开。
GROUP BY聚合在与子句结合使用时也非常有用。例如,我们可以得到每个城市观察到的最高低温:
选择城市,最大值(temp_lo)
从天气
按城市分组;
城市| 最大限度
---------------±----
海沃德 | 37
San Francisco | 46
(2 行)
这为每个城市提供了一个输出行。每个聚合结果都是根据与该城市匹配的表行计算的。我们可以使用以下方法过滤这些分组的行HAVING:
选择城市,最大值(temp_lo)
从天气
按城市分组
最大(temp_lo)< 40;
城市| 最大限度
---------±----
海沃德 | 37
(1 行)
这仅对所有值都低于 40 的城市给出了相同的结果。temp_lo最后,如果我们只关心名称以“ S”开头的城市,我们可能会这样做:
选择城市,最大值(temp_lo)
从天气
WHERE city LIKE ‘S%’ --(1)
按城市分组
最大(temp_lo)< 40;
(1)
LIKE运算符进行模式匹配,并在第9.7 节中解释。
了解聚合与SQLWHERE和HAVING子句之间的交互非常重要。WHERE和之间的根本区别在于HAVING:WHERE在计算组和聚合之前选择输入行(因此,它控制哪些行进入聚合计算),而HAVING在计算组和聚合之后选择组行。因此,该WHERE子句不得包含聚合函数;尝试使用聚合来确定哪些行将作为聚合的输入是没有意义的。另一方面,HAVING子句总是包含聚合函数。(严格来说,你可以写一个HAVING不使用聚合的子句,但它很少有用。在这个阶段可以更有效地使用相同的条件WHERE。)
在前面的示例中,我们可以在 中应用城市名称限制WHERE,因为它不需要聚合。这比将限制添加到 更有效HAVING,因为我们避免对所有未通过WHERE检查的行进行分组和聚合计算。