Postgresql 中文操作指南
9.21. Aggregate Functions #
Aggregate functions 从一组输入值中计算一个单一结果。内置通用聚合函数列在 Table 9.59 中,而统计聚合函数列在 Table 9.60 中。内置组内有序集聚合函数列在 Table 9.61 中,而内置组内假设集函数列在 Table 9.62 中。分组操作与聚合函数密切相关,列在 Table 9.63 中。聚合函数的特殊语法注意事项在 Section 4.2.7 中进行了解释。请查阅 Section 2.7 以获取其他介绍性信息。
支持 Partial Mode 的聚合函数有资格参与各种优化,例如并行聚合。
Table 9.59. General-Purpose Aggregate Functions
Function Description |
Partial Mode |
any_value ( anyelement ) → same as input type 从非空输入值返回任意值。 |
Yes |
array_agg ( anynonarray ) → anyarray 收集包括空值在内的所有输入值,形成一个数组。 |
Yes |
array_agg ( anyarray ) → anyarray 将所有输入数组连接成一个高一维的数组。(所有输入值必须具有相同维数,且不能为空或空值。) |
Yes |
avg ( smallint ) → numeric avg ( integer ) → numeric avg ( bigint ) → numeric avg ( numeric ) → numeric avg ( real ) → double precision avg ( double precision ) → double precision avg ( interval ) → interval 计算所有非空输入值的平均值(算术平均值)。 |
Yes |
bit_and ( smallint ) → smallint bit_and ( integer ) → integer bit_and ( bigint ) → bigint bit_and ( bit ) → bit 计算所有非空输入值的按位 AND。 |
Yes |
bit_or ( smallint ) → smallint bit_or ( integer ) → integer bit_or ( bigint ) → bigint bit_or ( bit ) → bit 计算所有非空输入值的按位 OR。 |
Yes |
bit_xor ( smallint ) → smallint bit_xor ( integer ) → integer bit_xor ( bigint ) → bigint bit_xor ( bit ) → bit 计算所有非空输入值的按位异或。可用作无序值集的检验和。 |
Yes |
bool_and ( boolean ) → boolean 当所有非空输入值都为真时返回真,否则返回假。 |
Yes |
bool_or ( boolean ) → boolean 当任何一个非空输入值都为真时返回真,否则返回假。 |
Yes |
count ( * ) → bigint 计算输入行数。 |
Yes |
count ( "any" ) → bigint 计算输入值非空的输入行数。 |
Yes |
every ( boolean ) → boolean 这是 SQL 标准等同于 bool_and 。 |
Yes |
json_agg ( anyelement ) → json jsonb_agg ( anyelement ) → jsonb 收集所有输入值(包括 Null 值)到一个 JSON 数组中。值按照 to_json 或 to_jsonb 转换为 JSON。 |
No |
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" } |
No |
json_object_agg ( key "any" , value "any" ) → json jsonb_object_agg ( key "any" , value "any" ) → jsonb 收集所有键/值对到一个 JSON 对象中。键参数强制转换为文本;值参数按照 to_json 或 to_jsonb 转换。值可以为 Null,但键不能为 Null。 |
No |
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,则跳过输入内容。 |
No |
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。如果存在重复的键,则会引发异常。 |
No |
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] |
No |
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,则跳过输入内容。如果存在重复的键,则会引发异常。 |
No |
max ( see text ) → same as input type 计算非 Null 输入值的最大值。适用于任何数字、字符串、日期/时间或枚举类型,以及 inet 、 interval 、 money 、 oid 、 pg_lsn 、 tid 、 xid8 以及这些类型的数组。 |
Yes |
min ( see text ) → same as input type 计算非 Null 输入值的最小值。适用于任何数字、字符串、日期/时间或枚举类型,以及 inet 、 interval 、 money 、 oid 、 pg_lsn 、 tid 、 xid8 以及这些类型的数组。 |
Yes |
range_agg ( value anyrange ) → anymultirange range_agg ( value anymultirange ) → anymultirange 计算非 Null 输入值的并集。 |
No |
range_intersect_agg ( value anyrange ) → anyrange range_intersect_agg ( value anymultirange ) → anymultirange 计算非 Null 输入值的交集。 |
No |
json_agg_strict ( anyelement ) → json jsonb_agg_strict ( anyelement ) → jsonb 收集所有输入值,跳过 Null 值,放入一个 JSON 数组中。值按照 to_json 或 to_jsonb 转换为 JSON。 |
No |
string_agg ( value text , delimiter text ) → text string_agg ( value bytea , delimiter bytea ) → bytea 将非 Null 输入值连接到一个字符串中。第一个值之后的每个值之前都有相应的 delimiter (如果该值不为 Null)。 |
Yes |
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 输入值的总和。 |
Yes |
xmlagg ( xml ) → xml 连接非 Null XML 输入值(请参阅 Section 9.15.1.7 )。 |
No |
应该注意,除了 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_语句进行控制,如 Section 4.2.7所示。或者,通常会提供来自排序子查询的输入值。例如:
SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
当心如果外部查询级别包含其他处理,如连接,此方法可能会失败,因为这可能导致在计算聚合之前重新对子查询的输出进行排序。
Note
布尔聚合 bool_and 和 bool_or 对应于标准 SQL 聚合 every 和 any 或 some。PostgreSQL 支持 every,但不支持 any 或 some,因为标准语法中存在歧义:
SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;
在此,ANY 可被认为要么是引入一个子查询,要么是作为聚合函数,如果子查询返回一行具有布尔值的查询。因此,无法向这些聚合赋予标准名称。
Note
习惯于使用其他 SQL 数据库管理系统的用户可能会对将 count 聚合应用于整个表时的性能感到失望。例如:
SELECT count(*) FROM sometable;
需要与表大小成比例的 esforço:PostgreSQL 将需要扫描整个表或某个索引的全部,其中包括表中的所有行。
Table 9.60列出了统计分析中通常使用的聚合函数。(这些函数只是为了避免常见聚合函数的排列混乱而单独列出。)显示为接受 numeric_type_的函数适用于所有类型 _smallint, integer, bigint, numeric, real_和 _double precision。说明中提及 _N_处,指所有输入表达式均非 Null 的输入行数。在所有情况下,如果计算没有意义(例如当 _N_为零时),将返回 null。
Table 9.60. Aggregate Functions for Statistics
Function Description |
Partial Mode |
corr ( Y double precision , X double precision ) → double precision 计算相关系数。 |
Yes |
covar_pop ( Y double precision , X double precision ) → double precision 计算总体的协方差。 |
Yes |
covar_samp ( Y double precision , X double precision ) → double precision 计算样本协方差。 |
Yes |
regr_avgx ( Y double precision , X double precision ) → double precision 计算自变量 sum(_X )/ N_ 的平均值。 |
Yes |
regr_avgy ( Y double precision , X double precision ) → double precision 计算自变量的平均值, sum(_Y )/ N_ 。 |
Yes |
regr_count ( Y double precision , X double precision ) → bigint 计算两项输入值均不为 null 的行数。 |
Yes |
regr_intercept ( Y double precision , X double precision ) → double precision 计算由 ( X , Y ) 对确定的最小二乘拟合线性方程的 y 截距。 |
Yes |
regr_r2 ( Y double precision , X double precision ) → double precision 计算相关系数的平方。 |
Yes |
regr_slope ( Y double precision , X double precision ) → double precision 计算由 ( X , Y ) 对确定的最小二乘拟合线性方程的斜率。 |
Yes |
regr_sxx ( Y double precision , X double precision ) → double precision 计算自变量的“平方和”, sum(_X ^2) - sum( X )^2/ N_ 。 |
Yes |
regr_sxy ( Y double precision , X double precision ) → double precision 计算自变量与因变量的“乘积和”, sum(_X * Y ) - sum( X ) * sum( Y )/ N_ 。 |
Yes |
regr_syy ( Y double precision , X double precision ) → double precision 计算因变量的“平方和”, sum(_Y ^2) - sum( Y )^2/ N_ 。 |
Yes |
stddev ( numeric_type ) → double precision 对于 real 或 double precision ,否则为 numeric 这是 stddev_samp 的历史别名。 |
Yes |
stddev_pop ( numeric_type ) → double precision 对于 real 或 double precision ,否则为 numeric 计算输入值的总体标准差。 |
Yes |
stddev_samp ( numeric_type ) → double precision 对于 real 或 double precision ,否则为 numeric 计算输入值的样本标准差。 |
Yes |
variance ( numeric_type ) → double precision 对于 real 或 double precision ,否则为 numeric 这是 var_samp 的历史别名。 |
Yes |
var_pop ( numeric_type ) → double precision 对于 real 或 double precision ,否则为 numeric 计算输入值的总体方差(总体标准差的平方)。 |
Yes |
var_samp ( numeric_type ) → double precision 对于 real 或 double precision ,否则为 numeric 计算输入值的样本方差(样本标准差的平方)。 |
Yes |
Table 9.61列出了一些使用 ordered-set aggregate_语法的聚合函数。这些函数有时称为“逆分布”函数。其聚合输入由 _ORDER BY_引入,这些函数还可以使用未被聚合但仅计算一次的 _direct argument。所有这些函数都忽略其聚合输入中的 null 值。对于那些接受 _fraction_参数的函数,分数值必须介于 0 到 1 之间;否则将引发错误。但是,null _fraction_值只会产生 null 结果。
Table 9.61. Ordered-Set Aggregate Functions
Function Description |
Partial Mode |
mode () WITHIN GROUP ( ORDER BY anyelement ) → anyelement 计算 mode ,聚合参数最常见的值(如果有多个相同频率的值,则任意选择第一个)。聚合参数必须是可排序类型。 |
No |
percentile_cont ( fraction double precision ) WITHIN GROUP ( ORDER BY double precision ) → double precision percentile_cont ( fraction double precision ) WITHIN GROUP ( ORDER BY interval ) → interval 计算 continuous percentile ,聚合参数值有序集中与指定 fraction 对应的一个值。如果需要,它将在相邻输入项之间进行插值。 |
No |
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 元素都将被替换为与该百分数对应的(可能经过插值的)值。 |
No |
percentile_disc ( fraction double precision ) WITHIN GROUP ( ORDER BY anyelement ) → anyelement 计算 discrete percentile ,聚合参数值有序集中第一个值,其在顺序中的位置等于或超出指定的 fraction 。聚合参数必须是可排序类型。 |
No |
percentile_disc ( fractions double precision[] ) WITHIN GROUP ( ORDER BY anyelement ) → anyarray 计算多个离散百分数。结果与 fractions 参数具有相同的维度,每个非 null 元素都将被替换为与该百分数对应的输入值。聚合参数必须是可排序类型。 |
No |
Table 9.62中列出的每个“假设集”聚合都与 Section 9.22中定义的同名窗口函数相关联。在每种情况下,聚合结果都是相关窗口函数针对由 _args_构建的“假设”行将返回的值(如果已将这样的行添加到由 _sorted_args_表示的排序行组中)。对于这些函数中的每一个,_args_中提供的直接参数列表必须与 _sorted_args_中提供的聚合参数的数量和类型匹配。与大多数内置聚合不同,这些聚合并非严格的,也就是说,它们不会删除包含 Null 值的输入行。Null 值按照 _ORDER BY_语句中指定的规则进行排序。
Table 9.62. Hypothetical-Set Aggregate Functions
Function Description |
Partial Mode |
rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) → bigint 计算假设行 的等级,包括空值即,其同侪组中第一行的行号。 |
No |
dense_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) → bigint 计算假设行的等级,不包括空值此函数有效地计算了同侪组。 |
No |
percent_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) → double precision 计算假设的行相对等级,即 ( rank - 1) / (总行数 - 1)。因此,该值介于 0 到 1(含)。 |
No |
cume_dist ( args ) WITHIN GROUP ( ORDER BY sorted_args ) → double precision 计算累积分布,即(先行行的数目或具有假设行的同级数)/(总行数)。因此,该值介于 1/ N 到 1。 |
No |
Table 9.63. Grouping Operations
Function Description |
GROUPING ( group_by_expression(s) ) → integer 返回指示当前分组集中不包括哪些 GROUP BY 表达式的位掩码。比特指定给与其最低位相对应的最右边的参数;每个比特为 0,如果对应的表达式包括在生成当前结果行的分组集的分组标准中,而为 1,如果未包括在其中。 |
Table 9.63中显示的分组操作与分组集(请参见 Section 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 均未在最后一行中按它们分组(因此,它是对所有输入行的聚合)。