选择 打开 改范围 完整检索页
受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10
当前 PostgreSQL 版本不在支持生命周期内。
您可以参阅当前版本的对应页面,或其他在上面列出的活跃大版本。

9.20. 聚合函数 #

聚合函数根据一组输入值计算出单个结果。内置的通用聚合函数列于Table 9.52,统计聚合函数列于Table 9.53。内置的组内有序集聚合函数列于Table 9.54,内置的组内假想集聚合函数列于Table 9.55。与聚合函数密切相关的分组操作列于Table 9.56。聚合函数的特殊语法说明见Section 4.2.7。更多入门信息请参见Section 2.7

Table 9.52. 通用聚合函数

函数 参数类型 返回类型 部分模式 描述
array_agg(expression) 任意非数组类型 参数类型的数组 No 将输入值(包括 null)串接为数组
array_agg(expression) 任意数组类型 与参数数据类型相同 No 将输入数组串接为维数多一维的数组(所有输入的维数必须相同,且不能是空数组或 null)
avg(expression) smallintintbigintrealdouble precisionnumericinterval 整数类型参数返回 numeric,浮点参数返回 double precision,其他情况与参数数据类型相同 所有非空输入值的平均值(算术平均值)
bit_and(expression) smallintintbigintbit 与参数数据类型相同 所有非空输入值的按位与;没有非空输入时为 null
bit_or(expression) smallintintbigintbit 与参数数据类型相同 所有非空输入值的按位或;没有非空输入时为 null
bool_and(expression) bool bool 所有输入值都为真时返回真,否则返回假
bool_or(expression) bool bool 至少一个输入值为真时返回真,否则返回假
count(*)   bigint 输入行数
count(expression) 任意 bigint expression 的值不为 null 的输入行数
every(expression) bool bool 等价于 bool_and
json_agg(expression) any json No 将值(包括 null)聚合为 JSON 数组
jsonb_agg(expression) any jsonb No 将值(包括 null)聚合为 JSON 数组
json_object_agg(name, value) (any, any) json No 将名称/值对聚合为 JSON 对象;值可以为 null,名称不能为 null
jsonb_object_agg(name, value) (any, any) jsonb No 将名称/值对聚合为 JSON 对象;值可以为 null,名称不能为 null
max(expression) 任意数值、字符串、日期/时间、网络或枚举类型,或这些类型的数组 与参数类型相同 所有非空输入值中 expression 的最大值
min(expression) 任意数值、字符串、日期/时间、网络或枚举类型,或这些类型的数组 与参数类型相同 所有非空输入值中 expression 的最小值
string_agg(expression, delimiter) texttext)或(byteabytea 与参数类型相同 No 将非空输入值串接为字符串,以分隔符分隔
sum(expression) smallintintbigintrealdouble precisionnumericintervalmoney smallintint 参数返回 bigintbigint 参数返回 numeric,其他情况与参数数据类型相同 对所有非空输入值的 expression 求和
xmlagg(expression) xml xml No 串接非空 XML 值(另见Section 9.14.1.7

应该注意的是,除了count之外,这些函数在没有选择行时返回空值。 特别地,行数的sum返回空(null),而不是预期的零,array_agg在没有输入行时返回空(null)而不是空数组。 coalesce函数可以在必要时用零或空数组代替空(null)。

支持部分模式的聚合函数可以参与并行聚合等多种优化。

Note

布尔聚合bool_andbool_or对应于标准 SQL 聚合everyanysome。至于anysome,标准语法似乎存在歧义:

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

此处的ANY既可以被视为引入一个子查询,也可以在该子查询返回一行布尔值时被视为聚合函数。因此,不能将标准名称用于这些聚合。

Note

习惯于其他 SQL 数据库管理系统的用户,可能会对count聚合用于整个表时的性能感到失望。如下查询:

SELECT count(*) FROM sometable;

所需的工作量与表大小成正比:PostgreSQL必须扫描整个表,或者完整扫描一个包含表中所有行的索引。

聚合函数 array_agg,json_agg, jsonb_agg,json_object_agg, jsonb_object_agg, string_agg,和 xmlagg,以及类似的用户定义的聚合函数,根据输入值的顺序产生富有意义的不同的结果值。 默认情况下,这种排序是不指定的,但可以通过在聚合调用中写入ORDER BY子句来控制,如Section 4.2.7所示。 或者,从排序的子查询提供输入值通常也可以。例如:

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

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

Table 9.53列出了统计分析常用的聚合函数。(将它们单独列出只是为了避免让更常用的聚合函数列表过于拥挤。)说明中提到的 N 表示所有输入表达式均非空的输入行数。在所有情况下,如果计算没有意义,例如 N 为零,都会返回空值。

Table 9.53. 用于统计的聚合函数

函数 参数类型 返回类型 部分模式 描述
corr(Y, X) double precision double precision Yes 相关系数
covar_pop(Y, X) double precision double precision Yes 总体协方差
covar_samp(Y, X) double precision double precision Yes 样本协方差
regr_avgx(Y, X) double precision double precision Yes 自变量的平均值(sum(X)/N
regr_avgy(Y, X) double precision double precision Yes 因变量的平均值(sum(Y)/N
regr_count(Y, X) double precision bigint Yes 两个表达式都非空的输入行数
regr_intercept(Y, X) double precision double precision Yes 由(XY)数值对确定的最小二乘拟合线性方程的 y 轴截距
regr_r2(Y, X) double precision double precision Yes 相关系数的平方
regr_slope(Y, X) double precision double precision Yes 由(XY)数值对确定的最小二乘拟合线性方程的斜率
regr_sxx(Y, X) double precision double precision Yes sum(X^2) - sum(X)^2/N(自变量的平方和
regr_sxy(Y, X) double precision double precision Yes sum(X*Y) - sum(X) * sum(Y)/N(自变量与因变量的乘积和
regr_syy(Y, X) double precision double precision Yes sum(Y^2) - sum(Y)^2/N(因变量的平方和
stddev(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric Yes stddev_samp 的历史别名
stddev_pop(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric Yes 输入值的总体标准差
stddev_samp(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric Yes 输入值的样本标准差
variance(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric Yes var_samp 的历史别名
var_pop(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric Yes 输入值的总体方差(总体标准差的平方)
var_samp(expression) smallintintbigintrealdouble precisionnumeric 浮点参数返回 double precision,其他情况返回 numeric Yes 输入值的样本方差(样本标准差的平方)

Table 9.54列出了一些使用有序集聚合语法的聚合函数。这些函数有时被称为逆分布函数。

Table 9.54. 有序集聚合函数

函数 直接参数类型 聚合参数类型 返回类型 部分模式 描述
mode() WITHIN GROUP (ORDER BY sort_expression) 任意可排序类型 与排序表达式相同 No 返回出现次数最多的输入值(若有多个结果同样频繁,则任意选择第一个)
percentile_cont(fraction) WITHIN GROUP (ORDER BY sort_expression) double precision double precisioninterval 与排序表达式相同 No 连续百分位数:返回排序中与指定比例对应的值,必要时在相邻输入项之间插值
percentile_cont(fractions) WITHIN GROUP (ORDER BY sort_expression) double precision[] double precisioninterval 排序表达式类型的数组 No 多个连续百分位数:返回形状与 fractions 参数一致的结果数组,将每个非空元素替换为与该百分位数对应的值
percentile_disc(fraction) WITHIN GROUP (ORDER BY sort_expression) double precision 任意可排序类型 与排序表达式相同 No 离散百分位数:返回排序位置等于或超过指定比例的第一个输入值
percentile_disc(fractions) WITHIN GROUP (ORDER BY sort_expression) double precision[] 任意可排序类型 排序表达式类型的数组 No 多个离散百分位数:返回形状与 fractions 参数一致的结果数组,将每个非空元素替换为与该百分位数对应的输入值

Table 9.54中列出的所有聚合函数都忽略其排序输入中的空值。对于接受 fraction 参数的函数,该比例值必须在 0 和 1 之间,否则会报错。但空的比例值只会产生空结果。

Table 9.55中列出的每个聚合函数都与Section 9.21中定义的同名窗口函数相关联。对于每个函数,如果将由 args 构造的假想行加入由 sorted_args 计算出的已排序行组,聚合结果就是相应窗口函数会为该行返回的值。

Table 9.55. 假想集聚合函数

函数 直接参数类型 聚合参数类型 返回类型 部分模式 描述
rank(args) WITHIN GROUP (ORDER BY sorted_args) VARIADIC "any" VARIADIC "any" bigint No 假设行的排名,重复行会造成排名空缺
dense_rank(args) WITHIN GROUP (ORDER BY sorted_args) VARIADIC "any" VARIADIC "any" bigint No 假设行的排名,没有空缺
percent_rank(args) WITHIN GROUP (ORDER BY sorted_args) VARIADIC "any" VARIADIC "any" double precision No 假设行的相对排名,范围为 0 到 1
cume_dist(args) WITHIN GROUP (ORDER BY sorted_args) VARIADIC "any" VARIADIC "any" double precision No 假设行的相对排名,范围为 1/N 到 1

对于每个假想集聚合函数,args 中给出的直接参数列表必须与 sorted_args 中给出的聚合参数在数量和类型上匹配。与大多数内置聚合不同,这些聚合不是严格的,也就是说,它们不会丢弃包含空值的输入行。空值按 ORDER BY 子句指定的规则排序。

Table 9.56. 分组操作

函数 返回类型 描述
GROUPING(args...) integer 表示哪些参数未包含在当前分组集中的整数位掩码

分组操作与分组集配合使用(参见Section 7.2.4),以区分结果行。传给GROUPING操作的参数不会实际求值,但它们必须与同一查询层级的GROUP BY子句中的表达式完全匹配。位的分配方式是将最右侧的参数对应到最低有效位;如果相应表达式包含在生成结果行的分组集的分组条件中,该位为 0,否则为 1。例如:

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