GROUP BY
语句能根据一个或多个列对结果集进行分组。
语法:
SELECT<expression1>, -- 指定包含在聚合函数中但必须添加到的表达式<expression2>,...<expressionN>FROM<table_name>GROUP BY<expression1>,<expression2>,...<expressionN>,
示例:统计不同籍贯的学生数量
SELECTnative_place,COUNT(*) AS num_stusFROMstudentsGROUP BYnative_place;-- 输出native_place num_stus------------ ----------GUANGZHOU 4GUANGXI 2BEIJING 1HUNAN 2
以上 SELECT
语句指定了两个列:native_place
学生的籍贯,num_stus
为计算字段(通过 COUNT(*)
函数建立)。
因为使用了 GROUP BY
,就不必指定要计算和估值的每个组了。系统会自动完成。GROUP BY
子句指示了 DBMS 分组数据,然后对每个组而不是整个结果集进行聚集。
HAVING
子句用于过滤分组(与 WHERE
子句的差别在于 WHERE
用于过滤行),且总是放在 GROUP BY
之后。
示例一:根据学生学号分组,并返回数学分数高于 80 分的那些学生学号
SELECTstudent_id,COUNT(*) AS maths_scoreFROMstudentsGROUP BYstudent_idHAVINGCOUNT(*) <= 80;
这条 SELECT
语句新增了 HAVING
子句,它过滤了 COUNT(*) <= 80
(数学分数低于 80 分)的那些分组。
在这里,WHERE
子句在这里不起作用,因为过滤是基于分组聚集值,而不是特定行的值。
示例二:返回编号和总成本小于 500 的记录
SELECTid,total_costFROMordersGROUP BYidHAVINGSUM(total_cost) < 500;
ORDER BY | GROUP BY |
---|---|
对产生的输出排序 | 对行分组,但输出可能不是分组的顺序 |
任意列都可以使用(甚至非选择的列也可以使用) | 只可能使用选择列或表达式列,而且必须使用每个选择列表达式 |
不一定需要 | 如果与聚集函数一起使用列(或表达式),则必须使用 |
在使用 GROUP BY
子句时,应该也给出 ORDER BY
子句。这是保证数据正确排序的唯一方法。千万不要仅依赖 GROUP BY
排序数据。
示例:检索包含三个或更多物品的订单号和订购物品的数量
SELECTorder_num,COUNT(*) AS itemsFROMOrderItemsGROUP BYorder_numHAVINGCOUNT(*) >= 3;-- 输出order_num items--------- -----20006 320007 520008 520009 3
要按订购物品的数目排序输出,需要添加 ORDER BY
子句。
SELECTorder_num,COUNT(*) AS itemsFROMOrderItemsGROUP BYorder_numHAVINGCOUNT(*) >= 3ORDER BYitems,order_num;order_num items--------- -----20006 320009 320007 520008 5
在这个例子中,使用 GROUP BY
子句按订单号(order_num
列)分组数据,以便 COUNT(*)
函数能够返回每个订单中的物品数目。HAVING
子句过滤数据,使得只返回包含三个或更多物品的订单。最后,用 ORDER BY
子句排序输出。