PG中文社区 /
mdi-home
首页 社区新闻 中文文档 加入ACE {{ item.text }} 登录
mdi-home 首页 mdi-chat-processing 社区新闻 mdi-book-open-variant 中文文档 mdi-account-multiple-check 加入ACE mdi-file-multiple-outline 相关资料 mdi-blank {{item.text}} mdi-exit-to-app 退出账号
【转】:PostgreSQL 聚合函数讲解 - 常用聚合函数

原作者:德哥  创作时间:2015-12-14 15:04:35+08  
doudou586 发布于2015-12-24 15:04:35           评论: 1   浏览: 18407   顶: 3573  踩: 4070 
本文转自社区强人Digoal的文章,原文地址:http://yq.aliyun.com/articles/144?spm=5176.team5.teamshow1.43.cdBp0X

PostgreSQL支持较多的聚合函数, 以PostgreSQL 9.4为例, 支持例如一般性的聚合, 统计学科的聚合, 排序集聚合, 假象集聚合等.

本文将对一般性聚合函数举例说明其功能和用法.

聚合函数有哪些,见 : http://www.postgresql.org/docs/9.4/static/functions-aggregate.html

以上所有聚合函数, 当没有行输入时, 除了count返回0, 其他都返回null.

使用sum, array_agg时, 当没有行输入, 返回NULL可能有点别扭, 那么你可以使用coalesce来替代NULL, 如coalesce(sum(x), 0) coalesce(array_agg(x), '{}'::int[])

例子 : 聚合后得到数组, null将计入数组元素

postgres=# select array_agg(id) from (values(null),(1),(2)) as t(id);
 array_agg  
------------
 {NULL,1,2}
(1 row)

算平均值是不计算null
postgres=# select avg(id) from (values(null),(1),(2)) as t(id);
        avg         
--------------------
 1.5000000000000000
(1 row)

算bit与|或 时也不计算NULL
postgres=# select bit_and(id) from (values(null),(1),(2)) as t(id);
 bit_and 
---------
       0
(1 row)
postgres=# select bit_or(id) from (values(null),(1),(2)) as t(id);
 bit_or 
--------
      3
(1 row)
算布尔逻辑时也不计算NULL
postgres=# select bool_and(id) from (values(null),(true),(false)) as t(id);
 bool_and 
----------
 f
(1 row)
every是bool_and的别名, 实际上是SQL标准中定义的. 
postgres=# select every(id) from (values(null),(true),(false)) as t(id);
 every 
-------
 f
(1 row)

SQL标准中还定义了any和some为bool_or的别名, 但是因为any和some还可以被解释为子查询, 所以在PostgreSQL中any和some的布尔逻辑聚合不可用.


postgres=# select any(id) from (values(null),(true),(false)) as t(id);
ERROR:  syntax error at or near "any"
LINE 1: select any(id) from (values(null),(true),(false)) as t(id);
               ^
postgres=# select some(id) from (values(null),(true),(false)) as t(id);
ERROR:  syntax error at or near "some"
LINE 1: select some(id) from (values(null),(true),(false)) as t(id);
               ^
bool_or的例子
postgres=# select bool_or(id) from (values(null),(true),(false)) as t(id);
 bool_or 
---------
 t
(1 row)

计算非空的表达式个数, count带表达式时, 不计算null
postgres=# select count(id) from (values(null),(1),(2)) as t(id);
 count 
-------
     2
(1 row)

计算表达式(含空值)的个数, count(*)计算null, 注意count(*)是一个独立的聚合函数. 请和count(express)区分开来.
postgres=# select count(*) from (values(null),(1),(2)) as t(id);
 count 
-------
     3
(1 row)
postgres=# select count(*) from (values(null),(null),(1),(2)) as t(id);
 count 
-------
     4
(1 row)

聚合后得到json, 不带key的json聚合
postgres=# select json_agg(id) from (values(null),(true),(false)) as t(id);
      json_agg       
---------------------
 [null, true, false]
(1 row)
聚合后得到json, 带key的json聚合, 注意key不能为null, 否则报错.
postgres=# select json_object_agg(c1,c2) from (values('a',null),('b',true),('c',false)) as t(c1,c2);
             json_object_agg             
-----------------------------------------
 { "a" : null, "b" : true, "c" : false }
(1 row)
postgres=# select json_object_agg(c1,c2) from (values(null,null),('b',true),('c',false)) as t(c1,c2);
ERROR:  22023: field name must not be null
LOCATION:  json_object_agg_transfn, json.c:1959

计算最大最小值, max, min都不计算null
postgres=# select max(id) from (values(null),(1),(2)) as t(id);
 max 
-----
   2
(1 row)
postgres=# select min(id) from (values(null),(1),(2)) as t(id);
 min 
-----
   1
(1 row)

聚合后得到字符串, 字符串聚合
postgres=# select string_agg(c1,'***') from (values('a',null),('b',true),('c',false)) as t(c1,c2);
 string_agg 
------------
 a***b***c
(1 row)
postgres=# select string_agg(id,'***') from (values(null),('digoal'),('zhou')) as t(id);
  string_agg   
---------------
 digoal***zhou
(1 row)

计算总和, sum不计算null, 当所有行都是null时, 即没有任何行输入, 返回null.
postgres=# select sum(id) from (values(null),(1),(2)) as t(id);
 sum 
-----
   3
(1 row)
postgres=# select sum(id::int) from (values(null),(null),(null)) as t(id);
 sum 
-----

(1 row)

聚合后得到xml
postgres=# select xmlagg(id::xml) from (values(null),('digoal'),('')) as t(id);
         xmlagg          
-------------------------
 digoal
(1 row)

某些聚合函数得到的结果可能和行的输入顺序有关, 例如array_agg, json_agg, json_object_agg, string_agg, and xmlagg, 以及某些自定义聚合函数. 如何来实现呢? 支持聚合函数中使用order by的PostgreSQL版本可以用如下语法 :

postgres=# select string_agg(id,'***' order by id) from (values(null),('digoal'),('zhou')) as t(id);
  string_agg   
---------------
 digoal***zhou
(1 row)
postgres=# select string_agg(id,'***' order by id desc) from (values(null),('digoal'),('zhou')) as t(id);
  string_agg   
---------------
 zhou***digoal
(1 row)
不支持聚合函数中使用order by的PostgreSQL版本, 可以用如下语法 : 
SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
postgres=# select string_agg(id,'***') from (select id from (values(null),('digoal'),('zhou')) as t(id) order by id desc) t;
  string_agg   
---------------
 zhou***digoal
(1 row)

[参考]

  1. http://www.postgresql.org/docs/9.4/static/functions-aggregate.html
  2. http://www.postgresql.org/docs/9.4/static/functions-xml.html
  3. src/backend/utils/adt

这些函数的代码在src/backend/utils/adt这里可以查询到, 对应各自的类型.


评论:1   浏览: 18407                   顶: 3573  踩: 4070 

请在登录后发表评论,否则无法保存。

1# __ xiaowu 回答于 2024-04-21 07:34:41+08
女生网名三个字高冷:https://www.nanss.com/mingcheng/1185.html 微信名字大全:https://www.nanss.com/mingcheng/739.html 霸气的游戏名:https://www.nanss.com/mingcheng/958.html 员工对公司的建议简短:https://www.nanss.com/gongzuo/643.html 自我崩溃自我治愈的句子:https://www.nanss.com/yulu/1105.html LOL高素质有内涵名字:https://www.nanss.com/mingcheng/1135.html 班干部会议记录:https://www.nanss.com/xuexi/556.html 女网名唯美有气质:https://www.nanss.com/mingcheng/740.html 临时请假理由靠谱点的:https://www.nanss.com/gongzuo/575.html 六字网名简单干净:https://www.nanss.com/mingcheng/623.html 仙女味的闺蜜网名:https://www.nanss.com/mingcheng/1355.html 入职感言简单明了:https://www.nanss.com/gongzuo/562.html 超级网名:https://www.nanss.com/mingcheng/1365.html 阿狸网名:https://www.nanss.com/mingcheng/1242.html 小清新网名:https://www.nanss.com/mingcheng/1177.html 打动女生情话:https://www.nanss.com/yulu/542.html 好听的网络名称:https://www.nanss.com/mingcheng/1456.html 超可爱的网名:https://www.nanss.com/mingcheng/1384.html 开启上班模式心情短语:https://www.nanss.com/yulu/690.html 泰坦尼克号经典台词:https://www.nanss.com/shenghuo/755.html 辞职信个人原因辞职信:https://www.nanss.com/gongzuo/587.html 我走了的说说心情短语:https://www.nanss.com/wenan/1270.html 油菜花开的句子唯美:https://www.nanss.com/yulu/1348.html 霸气冷酷吃鸡名字女:https://www.nanss.com/mingcheng/815.html 表达思念的句子:https://www.nanss.com/yulu/1035.html 微信名字微信昵称简单气质:https://www.nanss.com/mingcheng/962.html 好听稀少的游戏ID:https://www.nanss.com/mingcheng/669.html 特别的游戏名字:https://www.nanss.com/mingcheng/1091.html 订婚祝福语:https://www.nanss.com/yulu/526.html 非主流网名情侣:https://www.nanss.com/mingcheng/1474.html



发表评论:
加入我们
QQ群1:5276420
QQ群2:3336901
QQ群3:254622631
文档群:150657323
文档翻译平台:按此访问
社区邮件列表:按此订阅
商业支持
扫码关注
加入我们
QQ群1:5276420
QQ群2:3336901
QQ群3:254622631
文档群:150657323
文档翻译平台:按此访问
社区邮件列表:按此订阅
商业支持
扫码关注
© PostgreSQL中文社区 ... (自2010年起)