聚合函数从一个输入值的集合计算出一个单一结果。内置的通用聚合函数在表 9.62中列出,而统计聚合函数在表 9.63中列出。内置的组内有序集聚合函数在表 9.64中列出,而内置的组内假想集聚合在表 9.65中列出。与聚合函数紧密相关的分组操作在表 9.66中列出。第 4.2.7 节中会解释针对聚合函数的特殊语法注意事项。更多入门信息请参考第 2.7 节。
支持部分模式的聚合函数能够参与各种优化,例如并行聚合。
虽然下面所有聚合函数都接受可选的ORDER BY子句(详见第 4.2.7 节),但这里只在输出受排序影响的聚合函数签名中列出了该子句。
表 9.62. 通用聚合函数
|
函数
描述
|
部分模式 |
|
any_value ( anyelement ) → 与输入类型相同
从非空输入值中返回任意一个值。
|
是 |
|
array_agg ( anynonarray ORDER BY input_sort_columns ) → anyarray
将所有输入值,包括空值,收集到一个数组中。
|
是 |
|
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
计算所有非空输入值的平均值(算术平均值)。
|
是 |
|
bit_and ( smallint ) → smallint
bit_and ( integer ) → integer
bit_and ( bigint ) → bigint
bit_and ( bit ) → bit
计算所有非空输入值的按位与。
|
是 |
|
bit_or ( smallint ) → smallint
bit_or ( integer ) → integer
bit_or ( bigint ) → bigint
bit_or ( bit ) → bit
计算所有非空输入值的按位或。
|
是 |
|
bit_xor ( smallint ) → smallint
bit_xor ( integer ) → integer
bit_xor ( bigint ) → bigint
bit_xor ( bit ) → bit
计算所有非空输入值的按位异或。可用作一组无序的值集合的校验和。
|
是 |
|
bool_and ( boolean ) → boolean
如果全部非空输入值都为真则返回真,否则返回假。
|
是 |
|
bool_or ( boolean ) → boolean
如果任何非空输入值为真则返回真,否则返回假。
|
是 |
|
count ( * ) → bigint
计算输入行的数量。
|
是 |
|
count ( "any" ) → bigint
计算输入值不为空的输入行的数量。
|
是 |
|
every ( boolean ) → boolean
这是标准 SQL 中与bool_and等价的函数。
|
是 |
|
json_agg ( anyelement ORDER BY input_sort_columns ) → json
jsonb_agg ( anyelement ORDER BY input_sort_columns ) → jsonb
将所有输入值(包括空值)收集到一个JSON数组中。根据to_json或to_jsonb将值转换为JSON。
|
否 |
|
json_agg_strict ( anyelement ) → json
jsonb_agg_strict ( anyelement ) → jsonb
将所有非空输入值收集到一个JSON数组中,跳过空值。根据to_json或to_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_json或to_jsonb进行转换。值可以为空,但键不能(为空)。
|
否 |
|
json_object_agg_strict ( key "any", value "any" ) → json
jsonb_object_agg_strict ( key "any", value "any" ) → jsonb
将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_json或to_jsonb进行转换。key不能为空。如果value为空,则跳过该条目。
|
否 |
|
json_object_agg_unique ( key "any", value "any" ) → json
jsonb_object_agg_unique ( key "any", value "any" ) → jsonb
将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_json或to_jsonb进行转换。值可以为空,但键不能为空。如果存在重复键,则会抛出错误。
|
否 |
|
json_object_agg_unique_strict ( key "any", value "any" ) → json
jsonb_object_agg_unique_strict ( key "any", value "any" ) → jsonb
将所有键/值对收集到一个JSON对象中。键参数强制转换为文本;值参数按照to_json或to_jsonb进行转换。key不能为空。如果value为空,则跳过该条目。如果存在重复键,则会抛出错误。
|
否 |
|
max ( 见说明 ) → 与输入类型相同
计算非空输入值的最大值。适用于任何数字、字符串、日期/时间或枚举类型,以及bytea、inet、interval、money、oid、pg_lsn、tid、xid8,以及包含可排序数据类型的数组和复合类型。
|
是 |
|
min ( 见说明 ) → 与输入类型相同
计算非空输入值的最小值。适用于任何数字、字符串、日期/时间或枚举类型,以及bytea、inet、interval、money、oid、pg_lsn、tid、xid8,以及包含可排序数据类型的数组和复合类型。
|
是 |
|
range_agg ( value anyrange ) → anymultirange
range_agg ( value anymultirange ) → anymultirange
计算非空输入值的并集。
|
否 |
|
range_intersect_agg ( value anyrange ) → anyrange
range_intersect_agg ( value anymultirange ) → anymultirange
计算非空输入值的交集。
|
否 |
|
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
计算非空输入值的总和。
|
是 |
|
xmlagg ( xml ORDER BY input_sort_columns ) → xml
连接非空的 XML 输入值(参见第 9.15.1.8 节)。
|
否 |
需要注意,除了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,因为标准语法中存在歧义:
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表示所有输入表达式都非空的输入行数。无论哪种情况,如果计算没有意义,例如N为 0,就返回 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
计算两个输入都非空的行数。
|
是 |
|
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 ) → 对于real或double precision输入,返回double precision;否则返回numeric
这是stddev_samp的一个历史别名。
|
是 |
|
stddev_pop ( numeric_type ) → 对于real或double precision输入,返回double precision;否则返回numeric
计算输入值的总体标准差。
|
是 |
|
stddev_samp ( numeric_type ) → 对于real或double precision输入,返回double precision;否则返回numeric
计算输入值的样本标准差。
|
是 |
|
variance ( numeric_type ) → 对于real或double precision输入,返回double precision;否则返回numeric
这是 var_samp 的一个历史别名。
|
是 |
|
var_pop ( numeric_type ) → 对于real或double precision输入,返回double precision;否则返回numeric
计算输入值的总体方差(总体标准差的平方)。
|
是 |
|
var_samp ( numeric_type ) → 对于real或double precision输入,返回double precision;否则返回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参数具有相同维数的数组,每个非空元素都被对应于该百分位数的输入值替换。聚合参数必须是可排序类型。
|
否 |
列在表 9.65中的每个“假想集”聚合都与第 9.22 节中定义的同名窗口函数相关联。在每种情况下,如果把由args构造的“假想”行加入到sorted_args表示的已排序行组中,聚合结果就是相关窗口函数会为该行返回的值。对于这些函数中的每一个,args中给出的直接参数列表必须与sorted_args中给出的聚合参数数量和类型匹配。与大多数内置聚合不同,这些聚合不是严格的,也就是说它们不会删除包含空值的输入行。空值根据ORDER BY子句中指定的规则排序。
表 9.65. 假想集聚合函数
|
函数
描述
|
部分模式 |
|
rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) → bigint
计算假设行的排名,允许空缺;即该行所属同等行组中第一行的行号。
|
否 |
|
dense_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) → bigint
计算假设行的排名,没有空缺;此函数实际上对同等行组进行计数。
|
否 |
|
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)
这里,前四行的grouping值为0,表明这些行按两个分组列正常分组。值1表明model未用于倒数第二、第三行的分组,值3则表明最后一行既未按make分组,也未按model分组(因此该行聚合了全部输入行)。