聚合函数从一组输入值计算单个结果。内置的通用聚合函数列在表 9.62中,而统计聚合函数列在表 9.63中。内置的组内有序集聚合函数列在表 9.64中,而内置的组内假设集(hypothetical-set)聚合函数列在表 9.65中。与聚合函数密切相关的分组操作列在表 9.66中。聚合函数的特殊语法注意事项在第 4.2.7 节中进行了说明。有关附加的介绍性信息,请参阅第 2.7 节。
  支持部分模式(Partial Mode)的聚合函数有资格参与各种优化,例如并行聚合。
  虽然所有下面的聚合函数都接受一个可选的 ORDER BY 子句(如第 4.2.7 节中所述),但该子句仅添加到输出受排序影响的聚合函数中。
  
    表 9.62. 通用聚合函数
    
      
        
          
          
        
        
          
            | 函数 描述 | 部分模式 | 
        
        
          
            |  any_value(anyelement) →与输入类型相同 返回非空输入值中的任意一个值。 | 是 | 
          
            |  array_agg(anynonarrayORDER BYinput_sort_columns) →anyarray 将所有输入值(包括 NULL)收集到一个数组中。 | 是 | 
          
            | array_agg(anyarrayORDER BYinput_sort_columns) →anyarray
 将所有输入数组连接成一个维度更高的数组。(输入必须具有相同的维度,并且不能是空或 NULL。) | 是 | 
          
            |   avg(smallint) →numeric avg(integer) →numeric
 avg(bigint) →numeric
 avg(numeric) →numeric
 avg(real) →double precision
 avg(double precision) →double precision
 avg(interval) →interval
 计算所有非 NULL 输入值的平均值(算术平均值)。 | 是 | 
          
            |  bit_and(smallint) →smallint bit_and(integer) →integer
 bit_and(bigint) →bigint
 bit_and(bit) →bit
 计算所有非 NULL 输入值的按位 AND。 | 是 | 
          
            |  bit_or(smallint) →smallint bit_or(integer) →integer
 bit_or(bigint) →bigint
 bit_or(bit) →bit
 计算所有非 NULL 输入值的按位 OR。 | 是 | 
          
            |  bit_xor(smallint) →smallint bit_xor(integer) →integer
 bit_xor(bigint) →bigint
 bit_xor(bit) →bit
 计算所有非 NULL 输入值的按位异或(XOR)。可用于无序值集的校验和。 | 是 | 
          
            |  bool_and(boolean) →boolean 如果所有非 NULL 输入值都为 true,则返回 true,否则返回 false。 | 是 | 
          
            |  bool_or(boolean) →boolean 如果任何非 NULL 输入值为 true,则返回 true,否则返回 false。 | 是 | 
          
            |  count(*) →bigint 计算输入行的数量。 | 是 | 
          
            | count("any") →bigint
 计算输入值非 NULL 的输入行的数量。 | 是 | 
          
            |  every(boolean) →boolean 这是 SQL 标准中与 bool_and等效的函数。 | 是 | 
          
            |  json_agg(anyelementORDER BYinput_sort_columns) →json  jsonb_agg(anyelementORDER BYinput_sort_columns) →jsonb 将所有输入值(包括 NULL)收集到一个 JSON 数组中。值将按照 to_json或to_jsonb进行 JSON 转换。 | 否 | 
          
            |  json_agg_strict(anyelement) →json  jsonb_agg_strict(anyelement) →jsonb 将所有输入值(跳过 NULL)收集到一个 JSON 数组中。值将按照 to_json或to_jsonb进行 JSON 转换。 | 否 | 
          
            |  json_arrayagg( [value_expression] [ORDER BYsort_expression] [ {NULL|ABSENT}ON NULL] [RETURNINGdata_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] ] [RETURNINGdata_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 BYinput_sort_columns) →json  jsonb_object_agg(key"any",value"any"ORDER BYinput_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进行转换。键参数不能为 NULL。如果值是 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进行转换。键参数不能为 NULL。如果值是 NULL,则跳过该条目。如果存在重复键,则会抛出错误。 | 否 | 
          
            |  max(参见文本) →与输入类型相同 计算非 NULL 输入值的最大值。适用于任何数值、字符串、日期/时间或枚举类型,以及 bytea、inet、interval、money、oid、pg_lsn、tid、xid8,以及包含可排序数据类型的数组和复合类型。 | 是 | 
          
            |  min(参见文本) →与输入类型相同 计算非 NULL 输入值的最小值。适用于任何数值、字符串、日期/时间或枚举类型,以及 bytea、inet、interval、money、oid、pg_lsn、tid、xid8,以及包含可排序数据类型的数组和复合类型。 | 是 | 
          
            |  range_agg(valueanyrange) →anymultirange range_agg(valueanymultirange) →anymultirange
 计算非 NULL 输入值的并集。 | 否 | 
          
            |  range_intersect_agg(valueanyrange) →anyrange range_intersect_agg(valueanymultirange) →anymultirange
 计算非 NULL 输入值的交集。 | 否 | 
          
            |  string_agg(valuetext,delimitertext) →text string_agg(valuebytea,delimiterbyteaORDER BYinput_sort_columns) →bytea
 将非 NULL 输入值连接成一个字符串。第一个值之后的每个值都前面带有相应的 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
 计算非 NULL 输入值的总和。 | 是 | 
          
            |  xmlagg(xmlORDER BYinput_sort_columns) →xml 将非 NULL XML 输入值连接起来(参见第 9.15.1.8 节)。 | 否 | 
        
      
     
   
  需要注意的是,除了 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 子句来控制,如第 4.2.7 节所示。或者,通常提供来自排序子查询的输入值可以奏效。例如:
  SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
  请注意,如果外部查询级别包含其他处理(例如 JOIN),此方法可能会失败,因为这可能导致子查询的输出在计算聚合之前被重新排序。
  
    注意
    布尔聚合函数 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.63 显示了通常用于统计分析的聚合函数。(这些只是为了避免将更常用的聚合函数列表弄得过于拥挤而分开列出。)描述中提到接受 numeric_type 的函数适用于所有类型 smallint、integer、bigint、numeric、real 和 double precision。在描述中提到 N 时,表示输入行为非 NULL 的输入行数。在所有情况下,如果计算无意义(例如 N 为零),则返回 NULL。
  
    表 9.63. 统计聚合函数
    
      
        
          
          
        
        
          
            | 函数 描述 | 部分模式 | 
        
        
          
            |   corr(Ydouble precision,Xdouble precision) →double precision 计算相关系数。 | 是 | 
          
            |   covar_pop(Ydouble precision,Xdouble precision) →double precision 计算总体协方差。 | 是 | 
          
            |   covar_samp(Ydouble precision,Xdouble precision) →double precision 计算样本协方差。 | 是 | 
          
            |  regr_avgx(Ydouble precision,Xdouble precision) →double precision 计算自变量的平均值,即 sum(。X)/N | 是 | 
          
            |  regr_avgy(Ydouble precision,Xdouble precision) →double precision 计算因变量的平均值,即 sum(。Y)/N | 是 | 
          
            |  regr_count(Ydouble precision,Xdouble precision) →bigint 计算两个输入值都非 NULL 的行的数量。 | 是 | 
          
            |   regr_intercept(Ydouble precision,Xdouble precision) →double precision 计算由 (X,Y) 对确定的最小二乘拟合线性方程的 y 截距。 | 是 | 
          
            |  regr_r2(Ydouble precision,Xdouble precision) →double precision 计算相关系数的平方。 | 是 | 
          
            |   regr_slope(Ydouble precision,Xdouble precision) →double precision 计算由 (X,Y) 对确定的最小二乘拟合线性方程的斜率。 | 是 | 
          
            |  regr_sxx(Ydouble precision,Xdouble precision) →double precision 计算自变量的“平方和”,即 sum(。X^2) - sum(X)^2/N | 是 | 
          
            |  regr_sxy(Ydouble precision,Xdouble precision) →double precision 计算独立变量与因变量的“乘积和”,即 sum(。X*Y) - sum(X) * sum(Y)/N | 是 | 
          
            |  regr_syy(Ydouble precision,Xdouble precision) →double precision 计算因变量的“平方和”,即 sum(。Y^2) - sum(Y)^2/N | 是 | 
          
            |   stddev(numeric_type) →double precisionforrealordouble precision, otherwisenumeric 这是 stddev_samp的历史别名。 | 是 | 
          
            |   stddev_pop(numeric_type) →double precisionforrealordouble precision, otherwisenumeric 计算输入值的总体标准差。 | 是 | 
          
            |   stddev_samp(numeric_type) →double precisionforrealordouble precision, otherwisenumeric 计算输入值的样本标准差。 | 是 | 
          
            |  variance(numeric_type) →double precisionforrealordouble precision, otherwisenumeric 这是 var_samp的历史别名。 | 是 | 
          
            |   var_pop(numeric_type) →double precisionforrealordouble precision, otherwisenumeric 计算输入值的总体方差(总体标准差的平方)。 | 是 | 
          
            |   var_samp(numeric_type) →double precisionforrealordouble precision, otherwisenumeric 计算输入值的样本方差(样本标准差的平方)。 | 是 | 
        
      
     
   
  列在表 9.64中的一些聚合函数使用了有序集聚合语法。这些函数有时被称为“逆分布”函数。它们的聚合输入由 ORDER BY 引入,并且它们还可以接受一个不被聚合但只计算一次的直接参数。所有这些函数都会忽略其聚合输入中的 NULL 值。对于那些接受 fraction 参数的函数,该分数值必须在 0 到 1 之间;否则会抛出错误。但是,NULL fraction 值只会产生 NULL 结果。
  
    表 9.64. 有序集聚合函数
    
      
        
          
          
        
        
          
            | 函数 描述 | 部分模式 | 
        
        
          
            |  mode()WITHIN GROUP(ORDER BYanyelement) →anyelement 计算众数,即聚合参数中最频繁出现的值(如果有多个值出现频率相同,则任意选择第一个)。聚合参数必须是可排序的类型。 | 否 | 
          
            |  percentile_cont(fractiondouble precision)WITHIN GROUP(ORDER BYdouble precision) →double precision percentile_cont(fractiondouble precision)WITHIN GROUP(ORDER BYinterval) →interval
 计算连续分位数,即对应于有序集聚合参数值中指定 fraction的值。这将在需要时插入相邻的输入项。 | 否 | 
          
            | percentile_cont(fractionsdouble precision[])WITHIN GROUP(ORDER BYdouble precision) →double precision[]
 percentile_cont(fractionsdouble precision[])WITHIN GROUP(ORDER BYinterval) →interval[]
 计算多个连续分位数。结果是一个与 fractions参数相同维度的数组,每个非 NULL 元素都替换为对应于该分位数的值(可能经过插值)。 | 否 | 
          
            |  percentile_disc(fractiondouble precision)WITHIN GROUP(ORDER BYanyelement) →anyelement 计算离散分位数,即有序集聚合参数值中,其位置等于或超过指定 fraction的第一个值。聚合参数必须是可排序的类型。 | 否 | 
          
            | percentile_disc(fractionsdouble precision[])WITHIN GROUP(ORDER BYanyelement) →anyarray
 计算多个离散分位数。结果是一个与 fractions参数相同维度的数组,每个非 NULL 元素都替换为对应于该分位数的输入值。聚合参数必须是可排序的类型。 | 否 | 
        
      
     
   
  
  列在表 9.65中的每个“假设集”聚合都与同名的窗口函数相关联,该函数定义在第 9.22 节中。在每种情况下,聚合的结果是关联窗口函数对于从 args 构建的“假设”行返回的值,如果该行已添加到由 sorted_args 表示的行的排序组中。对于这些函数中的每一个,args 中的直接参数列表必须与 sorted_args 中的聚合参数的数量和类型匹配。与大多数内置聚合函数不同,这些聚合函数不是严格的,即它们不会丢弃包含 NULL 的输入行。NULL 值根据 ORDER BY 子句中指定的规则进行排序。
  
    表 9.65. 假设集聚合函数
    
      
        
          
          
        
        
          
            | 函数 描述 | 部分模式 | 
        
        
          
            |  rank(args)WITHIN GROUP(ORDER BYsorted_args) →bigint 计算假设行的排名,带间隙;也就是说,同一对(peer)行的行号。 | 否 | 
          
            |  dense_rank(args)WITHIN GROUP(ORDER BYsorted_args) →bigint 计算假设行的排名,不带间隙;此函数有效地计算对(peer)组的数量。 | 否 | 
          
            |  percent_rank(args)WITHIN GROUP(ORDER BYsorted_args) →double precision 计算假设行的相对排名,即 (rank- 1) / (总行数 - 1)。因此,该值范围从 0 到 1。 | 否 | 
          
            |  cume_dist(args)WITHIN GROUP(ORDER BYsorted_args) →double precision 计算累积分布,即(排在假设行之前或与其同级的行数)/(总行数)。因此,该值范围从 1/N到 1。 | 否 | 
        
      
     
   
  
    表 9.66. 分组操作
    
      
        
          
        
        
          
            | 函数 描述 | 
        
        
          
            |  GROUPING(group_by_expression(s)) →integer 返回一个位掩码,指示哪些 GROUP BY表达式未包含在当前分组集中。位分配方式是,最右边的参数对应于最低有效位;如果对应的表达式包含在生成当前结果行的分组集的标准中,则该位为 0,如果不包含,则为 1。 | 
        
      
     
   
  在 表 9.66 中显示的分组操作用于与分组集(参见第 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 都未被分组(因此该行是对所有输入行的聚合)。