9.15. 聚集函数

聚集函数 从一套输入值里计算一个结果。 Table 9-43 显示了内建聚集函数。 聚集函数的特殊语法在 Section 4.2.7里解释。请参考 Part I 获取附加的介绍性信息。

Table 9-43. 聚集函数

函数参数类型返回类型描述
avg(expression) 所有输入值的均值(算术平均) smallint, integer, bigint, real, double precision, numeric, 或 interval. 对于任何整数类型输入,结果都是 numeric 类型。 对于任何浮点输入,结果都是 double precision 类型。 否则和输入数据类型相同。 所有输入值的平均(算术平均)。
count(*) bigint输入值的数量
count(expression)任意bigint 计算那些 expression 非 NULL 的输入的个数。
max(expression)任何数值,字串或者日期/时间类型与参数同类型所有输入值中, expression 的最大值
min(expression)任何数值,字串或者日期/时间类型与参数同类型所有输入值中, expression 的最小值
stddev(expression) smallint, integer, bigint, real, double precision, 或 numeric. 浮点数参数时是double precision, 否则 numeric输入值的标准采样偏差(sample standard deviation)
sum(expression) smallint, integer, bigint, real, double precision, numeric, 或者 interval smallintinteger输入 输出类型为 bigint。对于bigint输入输出类型为 numeric, 浮点数输入的结果是 double precision。 否则和输入数据类型相同。 所有输入值的 expression 的总和
variance(expression) smallint, integer, bigint, real, double precision, 或者 numeric. 浮点数参数是 double precision, 否则是 numeric输出值的采样方差(标准采样偏差的平方)。

请注意除了 count 以外, 这些函数在没有选中行时返回 NULL。 尤其要指出的是对零输入行进行 sum 将返回 NULL, 而不是我们预期的零。 必要时可以用 coalesce 把 NULL 替换成零。

注意: 习惯了使用其它 RDBMS 产品的用户可能会对 PostgreSQL 里面的一些聚集函数的性能特点感到奇怪,特别是对整个表进行聚集的时候 (换句话说,不声明 WHERE 子句的时候)。 比如,一个下面这样的查询:

SELECT min(col) from sometable;

将会被 PostgreSQL 以对整个表进行 顺序扫描的形式进行执行。而其它数据库系统可能会把这样的查询 优化成使用某个字段上的索引的方式(如果有索引的话)。 在 PostgreSQL 里 类似的还有,如果对整个表进行处理的话,聚集函数 max()count() 总是要求一次顺序扫描。

PostgreSQL 无法很容易地实现这样的 优化,因为它还允许用户定义的聚集查询。因为 min()max(),和 count() 都是使用一个聚集函数的普通 API 定义的,因此在某些场合里, 这些函数的执行并不需要规定"特殊转换"

幸运的是,对于 min()max(), 我们有些简单的方法来绕开。比如下面显示的查询就等效于上面的查询, 但是,如果在目标字段上有索引,那么它可以利用一个 B+ 树索引来优化。

SELECT col from sometable ORDER BY col ASC LIMIT 1;

类似的查询(通过把上面查询的 ASC 替换成 DESC 就行了)也可以用在 max() 的地方。

糟糕的是,在对全表操作的时候,没有类似简单的查询可以用于改进 count() 的性能。