GBase 8c
其他
文章

GBase 8c 表表达式-GROUP BY子句

发表于2023-12-07 11:41:0726次浏览2个评论

在通过了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里没有哪个值可以和每个组相关联起来。被分组的列可以在选择列表中引用是因为它们在每个组都有单一的值。

通常,如果一个表被分了组,那么没有在GROUP BY中列出的列都不能被引用,除非在聚集表达式中被引用。 一个用聚集表达式的例子是:

 

=> SELECT x, sum(y) FROM test1 GROUP BY x;

 x | sum

---+-----

 a |   4

 b |   5

 c |   2

(3 rows)

这里的sum是一个聚集函数,它在整个组上计算出一个单一值。

提示

没有聚集表达式的分组实际上计算了一个列中可区分值的集合,我们也可以用DISTINCT子句实现。

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

 

SELECT product_id, p.name, (sum(s.units) * p.price) AS sales

    FROM products p LEFT JOIN sales s USING (product_id)

    GROUP BY product_id, p.name, p.price;

在这个例子里,列product_id、p.name和p.price必须在GROUP BY子句里, 因为它们都在查询的选择列表里被引用到(但见下文)。列s.units不必在GROUP BY列表里,因为它只是在一个聚集表达式(sum(...))里使用,它代表一组产品的销售额。对于每种产品,这个查询都返回一个该产品的所有销售额的总和行。

如果产品表被建立起来,例如product_id是主键,那么在上面的例子中用product_id来分组就够了,因为名称和价格都是函数依赖于产品ID,并且关于为每个产品ID分组返回哪个名称和价格值就不会有歧义。

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


 

评论

登录后才可以发表评论
崔哥发表于 6个月前
梅花不肯傍春光,自向深冬著艳阳。龙笛远吹胡地月,燕钗初试汉宫妆。风虽强暴翻添思,雪欲侵凌更助香。应笑暂时桃李树,盗天和气作年芳。
用户头像
levvel发表于 2个月前
看完收获很大!