当前位置:   article > 正文

PostgreSQL之SELECT...GROUP BY...HAVING

postgresql select group by

1.SELECT...GROUP BY的使用

    PostgreSQL9.3官方文档:http://www.postgres.cn/docs/9.3/sql-select.html#SQL-GROUPBY

    SELECT查询在通过了WHERE过滤器之后,生成的输出表可以继续用GROUP BY 子句进行分组,然后用HAVING子句删除一些分组行。 

  1. SELECT select_list  
  2.  FROM ...  
  3.  [WHERE ...]  
  4.  GROUP BY grouping_column_reference [, grouping_column_reference]...  
  5. HAVING condition

    GROUP BY 子句 用于把那些在表中所列出的列上共享相同值的行聚集在一起。 这些列的列出顺序并没有什么关系。 效果是把每组共享相同值的行缩减为一个组行,它代表该组里的所有行。 这样就可以删除输出里的重复和/或计算应用于这些组的聚集。 比如:

  1. highgo=#  create table tests1(id int primary key,name varchar,num int);
  2. highgo=insert into tests1 values(1,'yy',3),(2,'ws',2),(3,'yy',6);
  3. highgo=select * from tests1;
  4.  id | name | num
  5. ----+------+-----
  6.   1 | yy   |   3
  7.   2 | ws   |   2
  8.   3 | yy   |   6
  9. (3 行记录)
  10. highgo=select name from tests1 group by name;
  11.  name
  12. ------
  13.  ws
  14.  yy
  15. (2 行记录)

    通常,如果一个表被分了组,那么没有在分组中引用的字段都不能引用,除了在聚集表达式中以外。 一个带聚集表达式的例子是: 

  1. highgo=select name,sum(num) from tests1 group by name;
  2.  name | sum
  3. ------+-----
  4.  ws   |   2
  5.  yy   |   9
  6. (2 行记录)

    这里的 sum 是一个聚集函数,它在整个组上计算一个数值。 有关可用的聚集函数的更多信息可以在 Section 9.15 中找到。 
    注意: 没有聚集表达式的分组实际上计算了一个字段中独立数值的集合。 我们也可以用 DISTINCT 子句实现。


2.常用的聚合函数

    PostgreSQL9.3中文文档:http://www.postgres.cn/docs/9.3/functions-aggregate.html

函数参数类型返回类型描述
avg(expression)smallint, int,       bigint, real, double       precision, numeric, or interval对于任何整数类型输入,结果都是numeric类型。   对于任何浮点输入,结果都是double precision类型。   否则和输入数据类型相同。所有输入值的均值(算术平均)
bit_and(expression)smallint, int, bigint, or       bit和参数数据类型相同所有非 NULL 输入值的按位与(AND),如果全部输入值皆为 NULL ,那么结果也为 NULL 。
bit_or(expression)smallint, int, bigint, or       bit和参数数据类型相同所有非 NULL 输入值的按位或(OR),如果全部输入值皆为 NULL ,那么结果也为 NULL 。
bool_and(expression)boolbool如果所有输入值都是真,则为真,否则为假。
bool_or(expression)boolbool如果至少有一个输入值为真,则为真,否则为假。
count(*) bigint输入行数
count(expression)任意bigint计算所有输入行中满足expression不为 NULL 的行数。
every(expression)boolbool等效于bool_and
json_agg(record)recordjson聚合记录作为JSON对象数组
max(expression)任意数组、数值、字符串、日期/时间类型和参数数据类型相同有输入行中expression的最大值
min(expression)任意数组、数值、字符串、日期/时间类型和参数数据类型相同所有输入行中expression的最小值
        string_agg(expression,                    delimiter)       (text, text) or (bytea, bytea)和参数数据类型相同输入值连接成为一个字符串,用分隔符分开
sum(expression)smallint, int,       bigint, real, double       precision, numeric, or       interval对于smallint或int输入,输出类型为bigint。   对于bigint输入,输出类型为numeric,对于浮点数输入,   输出类型为double precision。否则和输入数据类型相同。所有输入行的expression总和。


3.HAVING子句的使用 

    如果一个表已经用GROUP BY子句分了组,然后你又只对其中的某些组感兴趣, 那么就可以用HAVING子句,它很象WHERE子句,用于删除一个分了组的表中的一些组。 语法是: 

SELECT select_list FROM ... [WHERE ...] GROUP BY ... HAVING boolean_expression

    在 HAVING 子句中的表达式可以引用分组的表达式和未分组的表达式(后者必须涉及一个聚集函数)。

  1. highgo=select name,sum(num) from tests1 group by name having sum(num)>5;
  2.  name | sum
  3. ------+-----
  4.  yy   |   9
  5. (1 行记录)


 4.HAVING子句与WHERE子句的区别

  HAVING去除了一些不满足条件的组行。它与WHERE 不同:WHERE在使用GROUP BY之前过滤出单独的行, 而HAVING过滤由GROUP BY创建的行。 在condition 里引用的每个字段都必须无歧义地引用一个分组的行,除非引用出现在一个聚合函数里。

  HAVING的出现把查询变成一个分组的查询,即使没有GROUP BY 子句也这样。这一点和那些包含聚合函数但没有GROUP BY子句的查询里发生的事情是一样的。 所有选取的行都被认为会形成一个单一的组,而SELECT 列表和HAVING子句只能从聚合函数里面引用表的字段。 这样的查询在HAVING条件为真的时候将发出一个行,如果为非真,则返回零行。


参考博客:http://lvmy.iteye.com/blog/793428

转载于:https://my.oschina.net/liuyuanyuangogo/blog/514752

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/765328
推荐阅读
相关标签
  

闽ICP备14008679号