聚合函数根据一组输入值计算出单个结果。内置的普通聚合函数列于表 9.49和表 9.50。内置的有序集聚合函数列于表 9.51和表 9.52。聚合函数的特殊语法说明见第 4.2.7 节。更多入门信息请参见第 2.7 节。
表 9.49. 通用聚合函数
| 函数 | 参数类型 | 返回类型 | 描述 |
|---|
array_agg(expression) | 任意非数组类型 | 参数类型的数组 | 将输入值(包括 null)串接为数组 |
avg(expression) | smallint、int、bigint、real、double precision、numeric 或 interval | 整数类型参数返回 numeric,浮点参数返回 double precision,其他情况与参数数据类型相同 | 所有非空输入值的平均值(算术平均值) |
bit_and(expression) | smallint、int、bigint 或 bit | 与参数数据类型相同 | 所有非空输入值的按位与;没有非空输入时为 null |
bit_or(expression) | smallint、int、bigint 或 bit | 与参数数据类型相同 | 所有非空输入值的按位或;没有非空输入时为 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 | 将值(包括 null)聚合为 JSON 数组 |
json_object_agg(name, value) | (any, any)
| json | 将名称/值对聚合为 JSON 对象;值可以为 null,名称不能为 null |
max(expression) | 任意数值、字符串、日期/时间、网络或枚举类型,或这些类型的数组 | 与参数类型相同 | 所有非空输入值中 expression 的最大值 |
min(expression) | 任意数值、字符串、日期/时间、网络或枚举类型,或这些类型的数组 | 与参数类型相同 | 所有非空输入值中 expression 的最小值 |
string_agg(expression, delimiter) | (text,text)或(bytea,bytea) | 与参数类型相同 | 将非空输入值串接为字符串,以分隔符分隔 |
sum(expression) | smallint、int、bigint、real、double precision、numeric、interval 或 money | smallint 或 int 参数返回 bigint,bigint 参数返回 numeric,其他情况与参数数据类型相同 | 对所有非空输入值的 expression 求和 |
xmlagg(expression) | xml | xml | 串接非空 XML 值(另见第 9.14.1.7 节) |
需要注意,除了count之外,这些函数在没有选中任何行时都会返回空值。特别地,sum在没有输入行时返回空值,而不是预期中的零;array_agg在没有输入行时返回空值,而不是空数组。必要时,可以用coalesce函数把空值替换成零或空数组。
注意
布尔聚合bool_and和bool_or对应于标准 SQL 聚合every和any或some。至于any和some,标准语法似乎存在歧义:
SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;
此处的ANY既可以被视为引入一个子查询,也可以在该子查询返回一行布尔值时被视为聚合函数。因此,不能将标准名称用于这些聚合。
注意
习惯于其他 SQL 数据库管理系统的用户,可能会对count聚合用于整个表时的性能感到失望。如下查询:
SELECT count(*) FROM sometable;
所需的工作量与表大小成正比:PostgreSQL必须扫描整个表,或者完整扫描一个包含表中所有行的索引。
聚合函数array_agg、json_agg、json_object_agg、string_agg和xmlagg,以及类似的用户定义聚合函数,其结果值会随输入值的顺序发生实质性变化。默认情况下,输入顺序未指定,但可以在聚合调用中写入ORDER BY子句来控制,如第 4.2.7 节所示。也可以用已排序的子查询提供输入值,这通常也能奏效。例如:
SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
但这种语法在 SQL 标准中是不允许的,并且不可移植到其他数据库系统。
表 9.50列出了统计分析常用的聚合函数。(将它们单独列出只是为了避免让更常用的聚合函数列表过于拥挤。)说明中提到的 N 表示所有输入表达式均非空的输入行数。在所有情况下,如果计算没有意义,例如 N 为零,都会返回空值。
表 9.50. 用于统计的聚合函数
| 函数 | 参数类型 | 返回类型 | 描述 |
|---|
corr(Y, X) | double precision | double precision | 相关系数 |
covar_pop(Y, X) | double precision | double precision | 总体协方差 |
covar_samp(Y, X) | double precision | double precision | 样本协方差 |
regr_avgx(Y, X) | double precision | double precision | 自变量的平均值(sum(X)/N) |
regr_avgy(Y, X) | double precision | double precision | 因变量的平均值(sum(Y)/N) |
regr_count(Y, X) | double precision | bigint | 两个表达式都非空的输入行数 |
regr_intercept(Y, X) | double precision | double precision | 由(X,Y)数值对确定的最小二乘拟合线性方程的 y 轴截距 |
regr_r2(Y, X) | double precision | double precision | 相关系数的平方 |
regr_slope(Y, X) | double precision | double precision | 由(X,Y)数值对确定的最小二乘拟合线性方程的斜率 |
regr_sxx(Y, X) | double precision | double precision | sum(X^2) - sum(X)^2/N(自变量的“平方和”) |
regr_sxy(Y, X) | double precision | double precision | sum(X*Y) - sum(X) * sum(Y)/N(自变量与因变量的“乘积和”) |
regr_syy(Y, X) | double precision | double precision | sum(Y^2) - sum(Y)^2/N(因变量的“平方和”) |
stddev(expression) | smallint、int、bigint、real、double precision 或 numeric | 浮点参数返回 double precision,其他情况返回 numeric | stddev_samp 的历史别名 |
stddev_pop(expression) | smallint、int、bigint、real、double precision 或 numeric | 浮点参数返回 double precision,其他情况返回 numeric | 输入值的总体标准差 |
stddev_samp(expression) | smallint、int、bigint、real、double precision 或 numeric | 浮点参数返回 double precision,其他情况返回 numeric | 输入值的样本标准差 |
variance(expression) | smallint、int、bigint、real、double precision 或 numeric | 浮点参数返回 double precision,其他情况返回 numeric | var_samp 的历史别名 |
var_pop(expression) | smallint、int、bigint、real、double precision 或 numeric | 浮点参数返回 double precision,其他情况返回 numeric | 输入值的总体方差(总体标准差的平方) |
var_samp(expression) | smallint、int、bigint、real、double precision 或 numeric | 浮点参数返回 double precision,其他情况返回 numeric | 输入值的样本方差(样本标准差的平方) |
表 9.51列出了一些使用有序集聚合语法的聚合函数。这些函数有时被称为“逆分布”函数。
表 9.51. 有序集聚合函数
| 函数 | 直接参数类型 | 聚合参数类型 | 返回类型 | 描述 |
|---|
mode() WITHIN GROUP (ORDER BY sort_expression) | | 任意可排序类型 | 与排序表达式相同 | 返回出现次数最多的输入值(若有多个结果同样频繁,则任意选择第一个) |
percentile_cont(fraction) WITHIN GROUP (ORDER BY sort_expression) | double precision | double precision 或 interval | 与排序表达式相同 | 连续百分位点:返回排序中与指定比例对应的值,必要时在相邻输入项之间插值 |
percentile_cont(fractions) WITHIN GROUP (ORDER BY sort_expression) | double precision[]
| double precision 或 interval | 排序表达式类型的数组 | 多个连续百分位点:返回形状与 fractions 参数一致的结果数组,将每个非空元素替换为与该百分位点对应的值 |
percentile_disc(fraction) WITHIN GROUP (ORDER BY sort_expression) | double precision | 任意可排序类型 | 与排序表达式相同 | 离散百分位数:返回排序位置等于或超过指定比例的第一个输入值 |
percentile_disc(fractions) WITHIN GROUP (ORDER BY sort_expression) | double precision[]
| 任意可排序类型 | 排序表达式类型的数组 | 多个离散百分位数:返回形状与 fractions 参数一致的结果数组,将每个非空元素替换为与该百分位数对应的输入值 |
表 9.51中列出的所有聚合函数都忽略其排序输入中的空值。对于接受 fraction 参数的函数,该比例值必须在 0 和 1 之间,否则会报错。但 null 比例值只会产生 null 结果。
表 9.52中列出的每个聚合函数都与第 9.21 节中定义的同名窗口函数相关联。对于每个函数,如果将由 args 构造的“假想”行加入由 sorted_args 计算出的已排序行组,聚合结果就是相应窗口函数会为该行返回的值。
表 9.52. 假想集聚合函数
| 函数 | 直接参数类型 | 聚合参数类型 | 返回类型 | 描述 |
|---|
rank(args) WITHIN GROUP (ORDER BY sorted_args) | VARIADIC "any" | VARIADIC "any" | bigint | 假设行的排名,重复行会造成排名空缺 |
dense_rank(args) WITHIN GROUP (ORDER BY sorted_args) | VARIADIC "any" | VARIADIC "any" | bigint | 假设行的排名,没有空缺 |
percent_rank(args) WITHIN GROUP (ORDER BY sorted_args) | VARIADIC "any" | VARIADIC "any" | double precision | 假设行的相对排名,范围为 0 到 1 |
cume_dist(args) WITHIN GROUP (ORDER BY sorted_args) | VARIADIC "any" | VARIADIC "any" | double precision | 假设行的相对排名,范围为 1/N 到 1 |
对于每个假想集聚合函数,args 中给出的直接参数列表必须与 sorted_args 中给出的聚合参数在数量和类型上匹配。与大多数内置聚合不同,这些聚合不是严格的,也就是说,它们不会丢弃包含空值的输入行。空值按 ORDER BY 子句指定的规则排序。