聚合函数从一组输入值计算单个结果。内置的通用聚合函数列在表 9.62中,而统计聚合函数列在表 9.63中。内置的组内有序集聚合函数列在表 9.64中,而内置的组内假设集(hypothetical-set)聚合函数列在表 9.65中。与聚合函数密切相关的分组操作列在表 9.66中。聚合函数的特殊语法注意事项在第 4.2.7 节中进行了说明。有关附加的介绍性信息,请参阅第 2.7 节。
支持部分模式(Partial Mode)的聚合函数有资格参与各种优化,例如并行聚合。
虽然所有下面的聚合函数都接受一个可选的 ORDER BY 子句(如第 4.2.7
节中所述),但该子句仅添加到输出受排序影响的聚合函数中。
表 9.62. 通用聚合函数
|
函数 描述 |
部分模式 |
|---|---|
|
返回非空输入值中的任意一个值。 |
是 |
|
将所有输入值(包括 NULL)收集到一个数组中。 |
是 |
|
将所有输入数组连接成一个维度更高的数组。(输入必须具有相同的维度,并且不能是空或 NULL。) |
是 |
|
计算所有非 NULL 输入值的平均值(算术平均值)。 |
是 |
|
计算所有非 NULL 输入值的按位 AND。 |
是 |
|
计算所有非 NULL 输入值的按位 OR。 |
是 |
|
计算所有非 NULL 输入值的按位异或(XOR)。可用于无序值集的校验和。 |
是 |
|
如果所有非 NULL 输入值都为 true,则返回 true,否则返回 false。 |
是 |
|
如果任何非 NULL 输入值为 true,则返回 true,否则返回 false。 |
是 |
|
计算输入行的数量。 |
是 |
|
计算输入值非 NULL 的输入行的数量。 |
是 |
|
这是 SQL 标准中与 |
是 |
|
将所有输入值(包括 NULL)收集到一个 JSON 数组中。值将按照 |
否 |
|
将所有输入值(跳过 NULL)收集到一个 JSON 数组中。值将按照 |
否 |
|
其行为与
|
否 |
|
其行为与
|
否 |
|
将所有键/值对收集到一个 JSON 对象中。键参数被强制转换为文本;值参数按照 |
否 |
|
将所有键/值对收集到一个 JSON 对象中。键参数被强制转换为文本;值参数按照 |
否 |
|
将所有键/值对收集到一个 JSON 对象中。键参数被强制转换为文本;值参数按照 |
否 |
|
将所有键/值对收集到一个 JSON 对象中。键参数被强制转换为文本;值参数按照 |
否 |
|
计算非 NULL 输入值的最大值。适用于任何数值、字符串、日期/时间或枚举类型,以及 |
是 |
|
计算非 NULL 输入值的最小值。适用于任何数值、字符串、日期/时间或枚举类型,以及 |
是 |
|
计算非 NULL 输入值的并集。 |
否 |
|
计算非 NULL 输入值的交集。 |
否 |
|
将非 NULL 输入值连接成一个字符串。第一个值之后的每个值都前面带有相应的 |
是 |
|
计算非 NULL 输入值的总和。 |
是 |
|
将非 NULL XML 输入值连接起来(参见第 9.15.1.8 节)。 |
否 |
需要注意的是,除了 count 之外,这些函数在没有选择行时会返回 NULL。特别是,没有行的 sum 返回 NULL,而不是预期的零,而 array_agg 在没有输入行时返回 NULL
而不是空数组。如有必要,可以使用 coalesce 函数将 NULL 替换为零或空数组。
聚合函数 array_agg、json_agg、jsonb_agg、json_agg_strict、jsonb_agg_strict、json_object_agg、jsonb_object_agg、json_object_agg_strict、jsonb_object_agg_strict、json_object_agg_unique、jsonb_object_agg_unique、json_object_agg_unique_strict、jsonb_object_agg_unique_strict、string_agg 和
xmlagg,以及类似的自定义聚合函数,其产生有意义的结果值取决于输入值的顺序。默认情况下,此排序是不确定的,但可以通过在聚合调用中编写
ORDER BY 子句来控制,如第 4.2.7
节所示。或者,通常提供来自排序子查询的输入值可以奏效。例如:
SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
请注意,如果外部查询级别包含其他处理(例如 JOIN),此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前被重新排序。
布尔聚合函数 bool_and 和 bool_or 分别对应于标准 SQL
聚合函数 every 和 any 或 some。PostgreSQL 支持 every,但不支持 any 或 some,因为标准语法中存在固有的歧义。
SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;
在这里,ANY 可以被看作是引入子查询,或者是一个聚合函数,如果子查询返回一行布尔值。因此,不能为这些聚合函数提供标准名称。
对于习惯于使用其他 SQL 数据库管理系统的用户来说,当 count 聚合应用于整个表时,其性能可能会令人失望。类似这样的查询:
SELECT count(*) FROM sometable;
将需要与表大小成比例的开销:PostgreSQL 需要扫描整个表或包含表中所有行的索引的全部内容。
表 9.63
显示了通常用于统计分析的聚合函数。(这些只是为了避免将更常用的聚合函数列表弄得过于拥挤而分开列出。)描述中提到接受 numeric_type 的函数适用于所有类型 smallint、integer、bigint、numeric、real 和 double precision。在描述中提到 N 时,表示输入行为非 NULL
的输入行数。在所有情况下,如果计算无意义(例如 N 为零),则返回 NULL。
表 9.63. 统计聚合函数
列在表 9.64中的一些聚合函数使用了有序集聚合语法。这些函数有时被称为“逆分布”函数。它们的聚合输入由 ORDER BY
引入,并且它们还可以接受一个不被聚合但只计算一次的直接参数。所有这些函数都会忽略其聚合输入中的 NULL 值。对于那些接受 fraction 参数的函数,该分数值必须在 0 到 1 之间;否则会抛出错误。但是,NULL fraction 值只会产生 NULL 结果。
表 9.64. 有序集聚合函数
列在表 9.65中的每个“假设集”聚合都与同名的窗口函数相关联,该函数定义在第 9.22 节中。在每种情况下,聚合的结果是关联窗口函数对于从 args 构建的“假设”行返回的值,如果该行已添加到由 sorted_args 表示的行的排序组中。对于这些函数中的每一个,args 中的直接参数列表必须与 sorted_args 中的聚合参数的数量和类型匹配。与大多数内置聚合函数不同,这些聚合函数不是严格的,即它们不会丢弃包含
NULL 的输入行。NULL 值根据 ORDER BY 子句中指定的规则进行排序。
表 9.65. 假设集聚合函数
表 9.66. 分组操作
在 表 9.66 中显示的分组操作用于与分组集(参见第 7.2.4 节)结合使用,以区分结果行。 GROUPING 函数的参数实际上不会被评估,但它们必须与关联查询级别的 GROUP BY
子句中给出的表达式完全匹配。例如:
=>SELECT * FROM items_sold;make | model | sales -------+-------+------- Foo | GT | 10 Foo | Tour | 20 Bar | City | 15 Bar | Sport | 5 (4 rows)=>SELECT make, model, GROUPING(make,model), sum(sales) FROM items_sold GROUP BY ROLLUP(make,model);make | model | grouping | sum -------+-------+----------+----- Foo | GT | 0 | 10 Foo | Tour | 0 | 20 Bar | City | 0 | 15 Bar | Sport | 0 | 5 Foo | | 1 | 30 Bar | | 1 | 20 | | 3 | 50 (7 rows)
在此,前四行的 grouping 值 0
表明它们是正常分组的,按两个分组列进行分组。值 1 表示在倒数第二行中 model
未被分组,而值 3 表示在最后一行中 make 和 model 都未被分组(因此该行是对所有输入行的聚合)。