9.21. 聚合函数#
聚合函数根据一组输入值计算单个结果。内置通用聚合函数列在表 9.59中,而统计聚合函数列在表 9.60中。内置组内有序集聚合函数列在表 9.61中,而内置组内假设集聚合函数列在表 9.62中。与聚合函数密切相关的分组操作列在表 9.63中。聚合函数的特殊语法注意事项在第 4.2.7 节中进行了说明。有关其他介绍性信息,请参阅第 2.7 节。
支持部分模式的聚合函数有资格参与各种优化,例如并行聚合。
表 9.59 通用聚合函数
函数 说明 | 部分模式 |
---|---|
从非空输入值中返回一个任意值。 | 是 |
将所有输入值(包括空值)收集到一个数组中。 | 是 |
将所有输入数组连接成一个高一维度的数组。(所有输入必须具有相同的维度,并且不能是空或空值。) | 是 |
计算所有非空输入值的平均值(算术平均值)。 | 是 |
计算所有非空输入值的按位 AND。 | 是 |
计算所有非空输入值的按位或。 | 是 |
计算所有非空输入值的按位异或。可作为无序值集的校验和。 | 是 |
如果所有非空输入值都为 true,则返回 true,否则返回 false。 | 是 |
如果任何非空输入值为 true,则返回 true,否则返回 false。 | 是 |
计算输入行数。 | 是 |
计算输入值不为 null 的输入行数。 | 是 |
这是 SQL 标准中 | 是 |
将所有输入值(包括 null)收集到一个 JSON 数组中。值将根据 | 否 |
行为类似于
| 否 |
将所有键/值对收集到一个 JSON 对象中。键参数强制转换为文本;值参数按照 | 否 |
将所有键/值对收集到一个 JSON 对象中。键参数强制转换为文本;值参数按照 | 否 |
将所有键/值对收集到一个 JSON 对象中。键参数强制转换为文本;值参数按照 | 否 |
行为与
| 否 |
将所有键/值对收集到一个 JSON 对象中。键参数强制转换为文本;值参数按照 | 否 |
计算非空输入值的较大值。可用于任何数字、字符串、日期/时间或枚举类型,以及 | 是 |
计算非空输入值的最小值。可用于任何数字、字符串、日期/时间或枚举类型,以及 | 是 |
计算非空输入值的并集。 | 否 |
计算非空输入值的交集。 | 否 |
收集所有输入值(跳过空值),并将其放入 JSON 数组中。值将根据 | 否 |
将非空输入值连接成一个字符串。第一个值之后的每个值都将前置相应的 | 是 |
计算非空输入值的总和。 | 是 |
连接非空 XML 输入值(参见 第 9.15.1.7 节)。 | 否 |
需要注意的是,除了count
,当没有选择行时,这些函数会返回一个空值。特别是,没有行的sum
会返回空值,而不是人们期望的零,而array_agg
在没有输入行时会返回空值,而不是空数组。必要时,可以使用coalesce
函数将空值替换为零或空数组。
聚合函数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;
请注意,如果外部查询级别包含其他处理(例如联接),则此方法可能会失败,因为这可能会导致在计算聚合之前重新排序子查询的输出。
注意
布尔聚合bool_and
和bool_or
对应于标准 SQL 聚合every
和any
或some
。PostgreSQL支持every
,但不支持any
或some
,因为标准语法中存在歧义此处ANY
可以被视为引入子查询,或作为聚合函数,如果子查询返回一行布尔值。因此,无法将标准名称赋予这些聚合。
注意
习惯于使用其他 SQL 数据库管理系统的用户可能会对将count
聚合应用于整个表时的性能感到失望。类似这样的查询需要与表大小成比例的精力:PostgreSQL需要扫描整个表或包含表中所有行的索引的全部内容。
表 9.60显示了统计分析中通常使用的聚合函数。(这些函数被单独列出,只是为了避免与更常用的聚合函数混淆。)显示为接受*numeric_type
的函数可用于所有类型smallint
、integer
、bigint
、numeric
、real
和double precision
。如果描述中提到了N
,则表示所有输入表达式都为非空值的输入行的数量。在所有情况下,如果计算没有意义(例如,当N
*为零时),则返回 null。
表 9.60. 统计分析的聚合函数
表 9.61显示了一些使用有序集聚合语法的聚合函数。这些函数有时称为“逆分布”函数。它们的聚合输入由ORDER BY
引入,它们还可以采用一个未聚合的直接参数,但仅计算一次。所有这些函数都忽略其聚合输入中的空值。对于那些采用*fraction
参数的函数,分数值必须在 0 和 1 之间;如果不满足此条件,则会引发错误。但是,空fraction
*值只会产生空结果。
表 9.61. 有序集聚合函数
表 9.62中列出的每个“假设集”聚合都与第 9.22 节中定义的同名窗口函数关联。在每种情况下,聚合的结果都是关联窗口函数将为从*args
构建的“假设”行返回的值,如果已将该行添加到由sorted_args
表示的有序行组中。对于这些函数中的每一个,args
中给出的直接参数列表必须与sorted_args
*中给出的聚合参数的数量和类型匹配。与大多数内置聚合不同,这些聚合不是严格的,即它们不会删除包含空值的输入行。空值根据ORDER BY
子句中指定的规则进行排序。
表 9.62. 假设集聚合函数
表 9.63 分组操作
函数 说明 |
---|
返回一个位掩码,指示哪些 |
表 9.63中所示的分组操作与分组集(请参阅第 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
分组(因此是所有输入行的聚合)。