2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

9.21. 聚合函数 #

聚合函数从一组输入值计算单个结果。内置的通用聚合函数列在表 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. 通用聚合函数

函数

描述

部分模式

any_value ( anyelement ) → 与输入类型相同

返回非空输入值中的任意一个值。

array_agg ( anynonarray ORDER BY input_sort_columns ) → anyarray

将所有输入值(包括 NULL)收集到一个数组中。

array_agg ( anyarray ORDER BY input_sort_columns ) → anyarray

将所有输入数组连接成一个维度更高的数组。(输入必须具有相同的维度,并且不能是空或 NULL。)

avg ( smallint ) → numeric

avg ( integer ) → numeric

avg ( bigint ) → numeric

avg ( numeric ) → numeric

avg ( real ) → double precision

avg ( double precision ) → double precision

avg ( interval ) → interval

计算所有非 NULL 输入值的平均值(算术平均值)。

bit_and ( smallint ) → smallint

bit_and ( integer ) → integer

bit_and ( bigint ) → bigint

bit_and ( bit ) → bit

计算所有非 NULL 输入值的按位 AND。

bit_or ( smallint ) → smallint

bit_or ( integer ) → integer

bit_or ( bigint ) → bigint

bit_or ( bit ) → bit

计算所有非 NULL 输入值的按位 OR。

bit_xor ( smallint ) → smallint

bit_xor ( integer ) → integer

bit_xor ( bigint ) → bigint

bit_xor ( bit ) → bit

计算所有非 NULL 输入值的按位异或(XOR)。可用于无序值集的校验和。

bool_and ( boolean ) → boolean

如果所有非 NULL 输入值都为 true,则返回 true,否则返回 false。

bool_or ( boolean ) → boolean

如果任何非 NULL 输入值为 true,则返回 true,否则返回 false。

count ( * ) → bigint

计算输入行的数量。

count ( "any" ) → bigint

计算输入值非 NULL 的输入行的数量。

every ( boolean ) → boolean

这是 SQL 标准中与 bool_and 等效的函数。

json_agg ( anyelement ORDER BY input_sort_columns ) → json

jsonb_agg ( anyelement ORDER BY input_sort_columns ) → jsonb

将所有输入值(包括 NULL)收集到一个 JSON 数组中。值将按照 to_jsonto_jsonb 进行 JSON 转换。

json_agg_strict ( anyelement ) → json

jsonb_agg_strict ( anyelement ) → jsonb

将所有输入值(跳过 NULL)收集到一个 JSON 数组中。值将按照 to_jsonto_jsonb 进行 JSON 转换。

json_arrayagg ( [ value_expression ] [ ORDER BY sort_expression ] [ { NULL | ABSENT } ON NULL ] [ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ])

其行为与 json_array 相同,但作为聚合函数,它只有一个 value_expression 参数。如果指定了 ABSENT ON NULL,则会忽略 NULL 值。如果指定了 ORDER BY,则元素将按照该顺序出现在数组中,而不是按照输入顺序。

SELECT json_arrayagg(v) FROM (VALUES(2),(1)) t(v)[2, 1]

json_objectagg ( [ { key_expression { VALUE | ':' } value_expression } ] [ { NULL | ABSENT } ON NULL ] [ { WITH | WITHOUT } UNIQUE [ KEYS ] ] [ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ])

其行为与 json_object 相同,但作为聚合函数,它只有一个 key_expression 和一个 value_expression 参数。

SELECT json_objectagg(k:v) FROM (VALUES ('a'::text,current_date),('b',current_date + 1)) AS t(k,v){ "a" : "2022-05-10", "b" : "2022-05-11" }

json_object_agg ( key "any", value "any" ORDER BY input_sort_columns ) → json

jsonb_object_agg ( key "any", value "any" ORDER BY input_sort_columns ) → jsonb

将所有键/值对收集到一个 JSON 对象中。键参数被强制转换为文本;值参数按照 to_jsonto_jsonb 进行转换。值可以是 NULL,但键不能是 NULL。

json_object_agg_strict ( key "any", value "any" ) → json

jsonb_object_agg_strict ( key "any", value "any" ) → jsonb

将所有键/值对收集到一个 JSON 对象中。键参数被强制转换为文本;值参数按照 to_jsonto_jsonb 进行转换。键参数不能为 NULL。如果值是 NULL,则跳过该条目。

json_object_agg_unique ( key "any", value "any" ) → json

jsonb_object_agg_unique ( key "any", value "any" ) → jsonb

将所有键/值对收集到一个 JSON 对象中。键参数被强制转换为文本;值参数按照 to_jsonto_jsonb 进行转换。值可以是 NULL,但键不能是 NULL。如果存在重复键,则会抛出错误。

json_object_agg_unique_strict ( key "any", value "any" ) → json

jsonb_object_agg_unique_strict ( key "any", value "any" ) → jsonb

将所有键/值对收集到一个 JSON 对象中。键参数被强制转换为文本;值参数按照 to_jsonto_jsonb 进行转换。键参数不能为 NULL。如果值是 NULL,则跳过该条目。如果存在重复键,则会抛出错误。

max ( 参见文本 ) → 与输入类型相同

计算非 NULL 输入值的最大值。适用于任何数值、字符串、日期/时间或枚举类型,以及 byteainetintervalmoneyoidpg_lsntidxid8,以及包含可排序数据类型的数组和复合类型。

min ( 参见文本 ) → 与输入类型相同

计算非 NULL 输入值的最小值。适用于任何数值、字符串、日期/时间或枚举类型,以及 byteainetintervalmoneyoidpg_lsntidxid8,以及包含可排序数据类型的数组和复合类型。

range_agg ( value anyrange ) → anymultirange

range_agg ( value anymultirange ) → anymultirange

计算非 NULL 输入值的并集。

range_intersect_agg ( value anyrange ) → anyrange

range_intersect_agg ( value anymultirange ) → anymultirange

计算非 NULL 输入值的交集。

string_agg ( value text, delimiter text ) → text

string_agg ( value bytea, delimiter bytea ORDER BY input_sort_columns ) → bytea

将非 NULL 输入值连接成一个字符串。第一个值之后的每个值都前面带有相应的 delimiter(如果它不是 NULL)。

sum ( smallint ) → bigint

sum ( integer ) → bigint

sum ( bigint ) → numeric

sum ( numeric ) → numeric

sum ( real ) → real

sum ( double precision ) → double precision

sum ( interval ) → interval

sum ( money ) → money

计算非 NULL 输入值的总和。

xmlagg ( xml ORDER BY input_sort_columns ) → xml

将非 NULL XML 输入值连接起来(参见第 9.15.1.8 节)。


需要注意的是,除了 count 之外,这些函数在没有选择行时会返回 NULL。特别是,没有行的 sum 返回 NULL,而不是预期的零,而 array_agg 在没有输入行时返回 NULL 而不是空数组。如有必要,可以使用 coalesce 函数将 NULL 替换为零或空数组。

聚合函数 array_aggjson_aggjsonb_aggjson_agg_strictjsonb_agg_strictjson_object_aggjsonb_object_aggjson_object_agg_strictjsonb_object_agg_strictjson_object_agg_uniquejsonb_object_agg_uniquejson_object_agg_unique_strictjsonb_object_agg_unique_strictstring_aggxmlagg,以及类似的自定义聚合函数,其产生有意义的结果值取决于输入值的顺序。默认情况下,此排序是不确定的,但可以通过在聚合调用中编写 ORDER BY 子句来控制,如第 4.2.7 节所示。或者,通常提供来自排序子查询的输入值可以奏效。例如:

SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;

请注意,如果外部查询级别包含其他处理(例如 JOIN),此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前被重新排序。

注意

布尔聚合函数 bool_andbool_or 分别对应于标准 SQL 聚合函数 everyanysomePostgreSQL 支持 every,但不支持 anysome,因为标准语法中存在固有的歧义。

SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;

在这里,ANY 可以被看作是引入子查询,或者是一个聚合函数,如果子查询返回一行布尔值。因此,不能为这些聚合函数提供标准名称。

注意

对于习惯于使用其他 SQL 数据库管理系统的用户来说,当 count 聚合应用于整个表时,其性能可能会令人失望。类似这样的查询:

SELECT count(*) FROM sometable;

将需要与表大小成比例的开销:PostgreSQL 需要扫描整个表或包含表中所有行的索引的全部内容。

表 9.63 显示了通常用于统计分析的聚合函数。(这些只是为了避免将更常用的聚合函数列表弄得过于拥挤而分开列出。)描述中提到接受 numeric_type 的函数适用于所有类型 smallintintegerbigintnumericrealdouble precision。在描述中提到 N 时,表示输入行为非 NULL 的输入行数。在所有情况下,如果计算无意义(例如 N 为零),则返回 NULL。

表 9.63. 统计聚合函数

函数

描述

部分模式

corr ( Y double precision, X double precision ) → double precision

计算相关系数。

covar_pop ( Y double precision, X double precision ) → double precision

计算总体协方差。

covar_samp ( Y double precision, X double precision ) → double precision

计算样本协方差。

regr_avgx ( Y double precision, X double precision ) → double precision

计算自变量的平均值,即 sum(X)/N

regr_avgy ( Y double precision, X double precision ) → double precision

计算因变量的平均值,即 sum(Y)/N

regr_count ( Y double precision, X double precision ) → bigint

计算两个输入值都非 NULL 的行的数量。

regr_intercept ( Y double precision, X double precision ) → double precision

计算由 (X, Y) 对确定的最小二乘拟合线性方程的 y 截距。

regr_r2 ( Y double precision, X double precision ) → double precision

计算相关系数的平方。

regr_slope ( Y double precision, X double precision ) → double precision

计算由 (X, Y) 对确定的最小二乘拟合线性方程的斜率。

regr_sxx ( Y double precision, X double precision ) → double precision

计算自变量的“平方和”,即 sum(X^2) - sum(X)^2/N

regr_sxy ( Y double precision, X double precision ) → double precision

计算独立变量与因变量的“乘积和”,即 sum(X*Y) - sum(X) * sum(Y)/N

regr_syy ( Y double precision, X double precision ) → double precision

计算因变量的“平方和”,即 sum(Y^2) - sum(Y)^2/N

stddev ( numeric_type ) → double precision for real or double precision, otherwise numeric

这是 stddev_samp 的历史别名。

stddev_pop ( numeric_type ) → double precision for real or double precision, otherwise numeric

计算输入值的总体标准差。

stddev_samp ( numeric_type ) → double precision for real or double precision, otherwise numeric

计算输入值的样本标准差。

variance ( numeric_type ) → double precision for real or double precision, otherwise numeric

这是 var_samp 的历史别名。

var_pop ( numeric_type ) → double precision for real or double precision, otherwise numeric

计算输入值的总体方差(总体标准差的平方)。

var_samp ( numeric_type ) → double precision for real or double precision, otherwise numeric

计算输入值的样本方差(样本标准差的平方)。


列在表 9.64中的一些聚合函数使用了有序集聚合语法。这些函数有时被称为逆分布函数。它们的聚合输入由 ORDER BY 引入,并且它们还可以接受一个不被聚合但只计算一次的直接参数。所有这些函数都会忽略其聚合输入中的 NULL 值。对于那些接受 fraction 参数的函数,该分数值必须在 0 到 1 之间;否则会抛出错误。但是,NULL fraction 值只会产生 NULL 结果。

表 9.64. 有序集聚合函数

函数

描述

部分模式

mode () WITHIN GROUP ( ORDER BY anyelement ) → anyelement

计算众数,即聚合参数中最频繁出现的值(如果有多个值出现频率相同,则任意选择第一个)。聚合参数必须是可排序的类型。

percentile_cont ( fraction double precision ) WITHIN GROUP ( ORDER BY double precision ) → double precision

percentile_cont ( fraction double precision ) WITHIN GROUP ( ORDER BY interval ) → interval

计算连续分位数,即对应于有序集聚合参数值中指定 fraction 的值。这将在需要时插入相邻的输入项。

percentile_cont ( fractions double precision[] ) WITHIN GROUP ( ORDER BY double precision ) → double precision[]

percentile_cont ( fractions double precision[] ) WITHIN GROUP ( ORDER BY interval ) → interval[]

计算多个连续分位数。结果是一个与 fractions 参数相同维度的数组,每个非 NULL 元素都替换为对应于该分位数的值(可能经过插值)。

percentile_disc ( fraction double precision ) WITHIN GROUP ( ORDER BY anyelement ) → anyelement

计算离散分位数,即有序集聚合参数值中,其位置等于或超过指定 fraction 的第一个值。聚合参数必须是可排序的类型。

percentile_disc ( fractions double precision[] ) WITHIN GROUP ( ORDER BY anyelement ) → anyarray

计算多个离散分位数。结果是一个与 fractions 参数相同维度的数组,每个非 NULL 元素都替换为对应于该分位数的输入值。聚合参数必须是可排序的类型。


列在表 9.65中的每个假设集聚合都与同名的窗口函数相关联,该函数定义在第 9.22 节中。在每种情况下,聚合的结果是关联窗口函数对于从 args 构建的假设行返回的值,如果该行已添加到由 sorted_args 表示的行的排序组中。对于这些函数中的每一个,args 中的直接参数列表必须与 sorted_args 中的聚合参数的数量和类型匹配。与大多数内置聚合函数不同,这些聚合函数不是严格的,即它们不会丢弃包含 NULL 的输入行。NULL 值根据 ORDER BY 子句中指定的规则进行排序。

表 9.65. 假设集聚合函数

函数

描述

部分模式

rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) → bigint

计算假设行的排名,带间隙;也就是说,同一对(peer)行的行号。

dense_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) → bigint

计算假设行的排名,不带间隙;此函数有效地计算对(peer)组的数量。

percent_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) → double precision

计算假设行的相对排名,即 (rank - 1) / (总行数 - 1)。因此,该值范围从 0 到 1。

cume_dist ( args ) WITHIN GROUP ( ORDER BY sorted_args ) → double precision

计算累积分布,即(排在假设行之前或与其同级的行数)/(总行数)。因此,该值范围从 1/N 到 1。


表 9.66. 分组操作

函数

描述

GROUPING ( group_by_expression(s) ) → integer

返回一个位掩码,指示哪些 GROUP BY 表达式未包含在当前分组集中。位分配方式是,最右边的参数对应于最低有效位;如果对应的表达式包含在生成当前结果行的分组集的标准中,则该位为 0,如果不包含,则为 1。


表 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)

在此,前四行的 grouping0 表明它们是正常分组的,按两个分组列进行分组。值 1 表示在倒数第二行中 model 未被分组,而值 3 表示在最后一行中 makemodel 都未被分组(因此该行是对所有输入行的聚合)。

提交更正

如果您在文档中发现任何不正确的内容、与您对特定功能的体验不符的内容或需要进一步澄清的内容,请使用 此表单 报告文档问题。