Postgresql中的分组函数(group by 和 having)

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

SELECT select_list  
 FROM ...  
 [WHERE ...]  
 GROUP BY grouping_column_reference [, grouping_column_reference]...  


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

 

=> SELECT * FROM test1;  
 x | y  
---+---  
 a | 3  
 c | 2  
 b | 5  
 a | 1  
(4 rows)  
  
=> SELECT x FROM test1 GROUP BY x;  
 x  
---  
 a  
 b  
 c  
(3 rows)  

 


在第二个查询里,我们不能写成 SELECT * FROM test1 GROUP BY x, 因为字段 y 里没有哪个值可以和每个组相关联起来。 被分组的字段可以在选择列表中引用是因为它们每个组都有单一的数值。 

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

 

=> SELECT x, sum(y) FROM test1 GROUP BY x;  
 x | sum  
---+-----  
 a |   4  
 b |   5  
 c |   2  
(3 rows)  



这里的 sum 是一个聚集函数,它在整个组上计算一个数值。 有关可用的聚集函数的更多信息可以在 Section 9.15 中找到。 

    提示: 没有聚集表达式的分组实际上计算了一个字段中独立数值的集合。 我们也可以用 DISTINCT 子句实现(参阅Section 7.3.3)。 

这里是另外一个例子:它计算每种产品的总销售额。(而不是所有产品的总销售额)。 

SELECT pid, p.name, (sum(s.units) * p.price) AS sales  
  FROM products p LEFT JOIN sales s USING ( pid )  
  GROUP BY pid, p.name, p.price;  



在这个例子里,字段pid, p.name,和p.price必须在GROUP BY子句里, 因为它们都在查询选择列表里被引用到。 (根据产品表具体的设置的不同,名字和价格可能和产品 ID 完全无关,因此理论上额外的分组可能是不必的, 但是这些尚未实现。) 字段s.units不必在GROUP BY列表里,因为它只是在一个聚集表达式(sum(...)) 里使用,它代表一组产品的销售额。对于每种产品,这个查询都返回一个该产品的所有销售额的总和。 

在严格的 SQL 里,GROUP BY只能对源表的列进行分组,但 PostgreSQL 把这个扩展为也允许GROUP BY那些在选择列表中的字段。也允许对值表达式进行分组,而不仅是简单的字段. 

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

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

 



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

=> SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) > 3;  
 x | sum  
---+-----  
 a |   4  
 b |   5  
(2 rows)  
  
=> SELECT x, sum(y) FROM test1 GROUP BY x HAVING x < 'c';  
 x | sum  
---+-----  
 a |   4  
 b |   5  
(2 rows)  



然后是一个更现实的例子: 

SELECT product_id, p.name, (sum(s.units) * (p.price - p.cost)) AS profit  
    FROM products p LEFT JOIN sales s USING (product_id)  
    WHERE s.date > CURRENT_DATE - INTERVAL '4 weeks'  
    GROUP BY product_id, p.name, p.price, p.cost  
    HAVING sum(p.price * s.units) > 5000;  

 


在上面的例子里,WHERE子句用于那些非分组的字段选择数据行。 (表达式只是对那些最近四周发生的销售为真)。 而HAVING子句选择那些单价超过 5000 的组的行。 请注意聚集函数不需要在查询中的所有地方都一样。

 

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: PostgreSQLGROUP BY用于将结果集按照指定的列进行分组,并对每个组进行聚合操作,例如计算总和、平均值、最大值、最小值等。GROUP BY语句通常与SELECT语句一起使用,用于生成汇总报表或统计数据。在GROUP BY语句,可以使用聚合函数对每个组进行计算,也可以使用HAVING子句对分组后的结果进行筛选。GROUP BY语句的语法如下: SELECT column1, column2, ..., aggregate_function(column) FROM table_name WHERE condition GROUP BY column1, column2, ...; 其,column1, column2, ...是要分组的列,aggregate_function是聚合函数,table_name是要查询的表名,condition是查询条件。GROUP BY语句将结果按照指定的列进行分组,并对每个组进行聚合操作,最后返回每个组的聚合结果。 ### 回答2: 在PostgreSQLGROUP BY语句用于按照一个或多个列对查询结果进行分组。在具体应用,使用GROUP BY时通常会指定一个或多个聚合函数以在每个分组内做进一步计算,比如计算每个分组的数量、平均值、最大值、最小值等。 GROUP BY语法如下: ``` SELECT column1, column2, ..., aggregat_function(column_name) FROM table_name WHERE condition GROUP BY column1, column2, ...; ``` 参数解释: - column1, column2, ...:要从表选择的列的名称。 - aggregat_function(column_name):聚合函数的名称,采用函数名(column_name)的形式,其column_name是要执行相应聚合函数的列的名称。 - table_name:要查询的表的名称。 - condition:可选,指定筛选条件。 GROUP BY的工作原理是将查询结果按照分组列的值进行分组,并将每个分组内的数据进行聚合计算。例如,下面的查询语句使用GROUP BY对orders表的数据按照customer_id进行分组,并计算每个客户的订单数量和订单总金额。 ``` SELECT customer_id, COUNT(order_id), SUM(order_amount) FROM orders GROUP BY customer_id; ``` 这个查询语句将orders表的数据按照每个客户进行分组,并分别统计了每个客户的订单数量和订单总金额。如果没有GROUP BY子句,那么查询结果将是整张表的统计数据,而GROUP BY则将结果分组,使得我们可以对每个分组内的数据做聚合计算,得到更加详细的统计信息。 另外,GROUP BY还可以指定多个分组列,例如按照地区和年份对销售额进行分组: ``` SELECT region, YEAR(sale_date), SUM(sale_amount) FROM sales GROUP BY region, YEAR(sale_date); ``` 这个查询语句将sales表的数据按照地区和年份进行分组,并计算每个分组的销售总额。 在使用GROUP BY时,还需要特别注意以下几点: 1. SELECT子句的列必须要么出现在GROUP BY子句,要么被聚合函数所使用。 2. 可以通过使用HAVING子句来筛选分组结果,HAVING的使用方法和WHERE类似,但它用于筛选分组后的结果,而不是原始表的数据。 3. GROUP BY的效率较低,因为它需要对数据进行排序和分组计算,因此在使用GROUP BY时应该尽量减少分组列的数量和提高查询效率。 ### 回答3: PostgreSQL是一个流行的关系型数据库管理系统,它支持广泛的标准SQL语言特性,其包括GROUP BY子句。在查询的结果使用GROUP BY子句时,可以将结果按照指定字段的值进行分组并计算结果。下面是一些关于PostgreSQL GROUP BY使用的重要事项: 1. GROUP BY子句语法 GROUP BY子句用于将一个或多个列组合在一起并产生汇总结果。其一般形式如下: ``` SELECT column1, column2, ... FROM table_name WHERE conditions GROUP BY column1, column2, ... ``` 在GROUP BY子句,需要使用要分组的列名。 2. GROUP BY子句用途 GROUP BY子句通常用于统计查询,以便获得数据的聚合值。通过使用GROUP BY子句,可以将数据划分为几个细分组,并对每个组执行聚集计算。例如,可以使用GROUP BY计算每个销售员的销售金额总额。 3. GROUP BY子句的结果集 在使用GROUP BY子句后,查询将返回数据的汇总结果,而不是详细的行级数据。对于每个分组,都会计算并返回聚合值。这些聚合值可以是SUM、AVG、MAX、MIN或COUNT等。 4. GROUP BY子句和HAVING子句的区别 GROUP BY子句用于将数据分组并执行聚合计算,而HAVING子句用于过滤结果集分组。在HAVING子句,可以使用聚合函数,以便筛选满足特定条件的分组。如果使用WHERE子句,则会在分组之前进行过滤,这可能会导致结果不准确。 5. 其他GROUP BY子句的使用 除了使用GROUP BY子句对结果进行分组外,还可以使用一些其他子句,如ORDER BY和DISTINCT来控制结果集的顺序和唯一性。例如,可以使用ORDER BY对每个分组的聚合值进行排序,以便找到最大或最小的值。 总之,PostgreSQLGROUP BY子句是非常有用的,它可以帮助为数据集生成有用的汇总统计。必须注意,在使用GROUP BY时,您需要正确处理聚合函数的数据类型,并选择正确的分组列,以便获得准确的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值