编写高级 SELECT 语句 / GROUP BY 和 HAVING 子句 |
GROUP BY 子句将表分为几组。此子句通常与为每个这样的组生成总结值的聚集函数组合。编写 SELECT 语句中的某些示例显示了应用于整个表的聚集函数的用法。本章说明应用于行组的聚集函数。
图: 查询
SELECT DISTINCT customer_num FROM orders;
图: 查询
SELECT customer_num FROM orders GROUP BY customer_num;
GROUP BY 子句将行收集到组中,因此每一组中的每一行具有相同的客户号。在没有选择任何其它列的情况下,结束是唯一 customer_num 值的列表。
GROUP BY 子句的功能在将它与聚集函数配合使用时更明显。
图: 查询
SELECT order_num, COUNT (*) number, SUM (total_price) price FROM items GROUP BY order_num;
GROUP BY 子句导致 items 表的行数被收集为组,每个组由具有相同 order_num 值的行组成(即,将每个订单的商品收集在一起)。在数据库服务器构成组之后,就在每个组中应用聚集行数 COUNT 和 SUM 。
图: 查询结果
order_num number price 1001 1 $250.00 1002 2 $1200.00 1003 3 $959.00 1004 4 $1416.00 ⋮ 1021 4 $1614.00 1022 3 $232.00 1023 6 $824.00
该结果将 items 表的行收集到具有相同订单号的组中,并计算每个组中行的 COUNT 和价格的 SUM。
不能在 GROUP BY 子句中包含 TEXT 、BYTE 、CLOB 或 BLOB 列。要进行分组,必须能够进行排序,并且这些数据类型不存在自然排序顺序。
与 ORDER BY 子句不同,GROUP BY 子句不对数据进行排序。如果想要按特定顺序对数据进行排序,或在投影列表中的聚集上排序,那么在 GROUP BY 子句之后包含 ORDER BY 子句。
图: 查询
SELECT order_num, COUNT(*) number, SUM (total_price) price FROM items GROUP BY order_num ORDER BY price;
图: 查询结果
order_num number price 1010 2 $84.00 1011 1 $99.00 1013 4 $143.80 1022 3 $232.00 1001 1 $250.00 1020 2 $438.00 1006 5 $448.00 ⋮ 1002 2 $1200.00 1004 4 $1416.00 1014 2 $1440.00 1019 1 $1499.97 1021 4 $1614.00 1007 5 $1696.00
选择特定列一节描述如何在 ORDER BY 子句中使用整数来指示投影列表中列的位置。还可以在 GROUP BY 子句中使用整数来指示列名的位置或在 GROUP BY 列表中显示标号。
图: 查询
SELECT order_num, COUNT(*) number, SUM (total_price) price FROM items GROUP BY 1 ORDER BY 3;
构建查询时,Projection 子句的投影列表中的所有非聚集列还必须包含在 GROUP BY 子句中。具有 GROUP BY 子句的 SELECT 语句必须针对每一组返回一行。列出在 GROUP BY 后面的列能够在一组中只反映一个特异值。并且可以返回该值。但是,未列出在 GROUP BY 后面的列可在包含在组中的行中包含不同的值。
图: 查询
SELECT o.order_num, SUM (i.total_price) FROM orders o, items i WHERE o.order_date > '01/01/98' AND o.customer_num = 110 AND o.order_num = i.order_num GROUP BY o.order_num;
图: 查询结果
order_num (sum) 1008 $940.00 1015 $450.00