聚合函数 从一组输入值中计算单个结果。内置通用聚合函数列在 表 9.60 中,而统计聚合列在 表 9.61 中。内置组内有序集聚合函数列在 表 9.62 中,而内置组内假设集聚合函数列在 表 9.63 中。分组操作与聚合函数密切相关,列在 表 9.64 中。聚合函数的特殊语法注意事项在 第 4.2.7 节 中解释。请参阅 第 2.7 节 获取更多介绍性信息。
支持 部分模式 的聚合函数有资格参与各种优化,例如并行聚合。
虽然以下所有聚合函数都接受一个可选的 ORDER BY
子句(如 第 4.2.7 节 中所述),但该子句仅添加到其输出受排序影响的聚合函数中。
表 9.60. 通用聚合函数
函数
描述
|
部分模式 |
any_value ( anyelement ) → 与输入类型相同
从非空输入值中返回任意值。
|
是 |
array_agg ( anynonarray ORDER BY input_sort_columns ) → anyarray
将所有输入值(包括空值)收集到数组中。
|
是 |
array_agg ( anyarray ORDER BY input_sort_columns ) → anyarray
将所有输入数组连接成一个更高维度的数组。(所有输入都必须具有相同的维数,并且不能为空或为空值。)
|
是 |
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 转换。值可以为 null,但键不能为 null。
|
否 |
json_object_agg_strict ( key "any" , value "any" ) → json
jsonb_object_agg_strict ( key "any" , value "any" ) → jsonb
将所有键值对收集到一个 JSON 对象中。键参数被强制转换为文本;值参数根据 to_json 或 to_jsonb 转换。 key 不能为 null。如果 value 为 null,则跳过该条目。
|
否 |
json_object_agg_unique ( key "any" , value "any" ) → json
jsonb_object_agg_unique ( key "any" , value "any" ) → jsonb
将所有键值对收集到一个 JSON 对象中。键参数被强制转换为文本;值参数根据 to_json 或 to_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_json 或 to_jsonb 转换。 key 不能为 null。如果 value 为 null,则跳过该条目。如果存在重复键,则会抛出错误。
|
否 |
max ( see text ) → same as input type
计算非空输入值的最大值。适用于任何数字、字符串、日期/时间或枚举类型,以及 inet 、interval 、money 、oid 、pg_lsn 、tid 、xid8 和任何这些类型的数组。
|
是 |
min ( see text ) → same as input type
计算非空输入值的最小值。适用于任何数字、字符串、日期/时间或枚举类型,以及 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
将非空输入值连接成一个字符串。除第一个值以外的每个值前面都有相应的 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
返回 null,而不是人们可能期望的零,并且当没有输入行时,array_agg
返回 null,而不是空数组。如果需要,可以使用 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.61 显示了通常用于统计分析的聚合函数。(这些函数仅仅是为了避免在更常用的聚合列表中显得杂乱无章而分开。)显示为接受 numeric_type
的函数适用于所有类型 smallint
、integer
、bigint
、numeric
、real
和 double precision
。如果描述中提到了 N
,则它表示所有输入表达式均为非空值的输入行数。在所有情况下,如果计算没有意义,例如当 N
为零时,将返回 null。
表 9.61. 用于统计的聚合函数
函数
描述
|
部分模式 |
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 ) → 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.62 显示了一些使用有序集合聚合语法的聚合函数。这些函数有时被称为“逆分布”函数。它们的聚合输入由 ORDER BY
引入,它们也可能接受一个直接参数,该参数不会被聚合,但只计算一次。所有这些函数都忽略其聚合输入中的空值。对于那些接受fraction
参数的函数,分数值必须介于 0 和 1 之间;如果没有,则会抛出错误。但是,空fraction
值只会产生空结果。
表 9.62. 有序集合聚合函数
函数
描述
|
部分模式 |
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 参数维度相同的数组,其中每个非空元素都被替换为对应于该百分位数的(可能插值的)值。
|
否 |
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.63 中列出的每个“假设集合”聚合都与在第 9.22 节 中定义的具有相同名称的窗口函数相关联。在每种情况下,聚合的结果是关联窗口函数将在从args
构造的“假设” 行上返回的值,如果这样的行被添加到由sorted_args
表示的排序行组中。对于这些函数中的每一个,在args
中给出的直接参数列表必须与在sorted_args
中给出的聚合参数的数量和类型相匹配。与大多数内置聚合不同,这些聚合不是严格的,也就是说它们不会删除包含空值的输入行。空值按照 ORDER BY
子句中指定的规则排序。
表 9.63. 假设集合聚合函数
函数
描述
|
部分模式 |
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.64. 分组操作
函数
描述
|
GROUPING ( group_by_expression(s) ) → integer
返回一个位掩码,指示哪些 GROUP BY 表达式未包含在当前分组集中。位以最右边的参数对应最低有效位的方式分配;如果相应表达式包含在生成当前结果行的分组集的分组标准中,则每个位为 0,否则为 1。
|
表 9.64 中所示的分组操作与分组集结合使用(参见 第 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
都未在最后一行中分组(因此它是在所有输入行上的聚合)。