聚合函数
与大多数其他关系数据库产品一样,PostgreSQL支持聚合函数。聚合函数从多个输入行计算单个结果。例如,有聚合函数可以计算一组行的count、、(平均值)、(最大值)和(最小值)。sum``avg``max``min
举个例子,我们可以在任何地方找到最高的低温读数:
SELECT max(temp_lo) FROM weather; max
-----
46
(1 row)如果我们想知道阅读发生在哪个城市(或多个城市),我们可以尝试:
SELECT city FROM weather WHERE temp_lo = max(temp_lo); WRONG但这不起作用,因为聚合max不能在WHERE子句中使用。(存在此限制是因为WHERE子句确定哪些行将包含在聚合计算中;因此显然必须在计算聚合函数之前对其进行评估。)但是,通常情况下,可以重新陈述查询以实现所需的结果,这里使用子查询:
SELECT city FROM weather
WHERE temp_lo = (SELECT max(temp_lo) FROM weather); city
---------------
San Francisco
(1 row)这是可以的,因为子查询是一个独立的计算,它可以独立于外部查询中发生的情况计算自己的聚合。
聚合与子句结合使用也非常有用GROUP BY。例如,我们可以使用以下命令获取每个城市观测到的读数数量和最高低温:
SELECT city, count(*), max(temp_lo)
FROM weather
GROUP BY city; city | count | max
---------------+-------+-----
Hayward | 1 | 37
San Francisco | 2 | 46
(2 rows)这为每个城市提供了一行输出。每个聚合结果都是根据与该城市匹配的表行计算得出的。我们可以使用以下方法过滤这些分组行HAVING:
SELECT city, count(*), max(temp_lo)
FROM weather
GROUP BY city
HAVING max(temp_lo) < 40; city | count | max
---------+-------+-----
Hayward | 1 | 37
(1 row)这只针对所有值低于 40 的城市给出相同的结果。temp_lo最后,如果我们只关心名称以“ S”开头的城市,我们可以这样做:
SELECT city, count(*), max(temp_lo)
FROM weather
WHERE city LIKE 'S%' -- (1)
GROUP BY city; city | count | max
---------------+-------+-----
San Francisco | 2 | 46
(1 row)该LIKE操作符进行模式匹配,在第 9.7 节中进行了解释。
理解聚合和SQL的WHERE和子句之间的相互作用非常重要。和HAVING之间的根本区别在于:在计算组和聚合之前选择输入行(因此,它控制哪些行进入聚合计算),而在计算组和聚合之后选择组行。 因此, 子句不能包含聚合函数;尝试使用聚合来确定哪些行将成为聚合的输入是没有意义的。 另一方面, 子句始终包含聚合函数。 (严格来说,您可以编写不使用聚合的子句,但它很少有用。 相同的条件可以在该阶段更有效地使用。)WHERE``HAVING``WHERE``HAVING``WHERE``HAVING``HAVING``WHERE
在上例中,我们可以在 中应用城市名称限制WHERE,因为它不需要聚合。这比在 中添加限制更有效率HAVING,因为我们避免对所有未通过检查的行进行分组和聚合计算WHERE。
选择进入聚合计算的行的另一种方法是使用FILTER,这是一个每个聚合选项:
SELECT city, count(*) FILTER (WHERE temp_lo < 45), max(temp_lo)
FROM weather
GROUP BY city; city | count | max
---------------+-------+-----
Hayward | 1 | 37
San Francisco | 1 | 46
(2 rows)FILTER与 非常相似WHERE,只不过它只从它所附加的特定聚合函数的输入中删除行。此处,聚合count仅计算temp_lo低于 45 的行;但max聚合仍应用于所有行,因此它仍会找到 46 的读数。