————介绍如何分组数据,以便汇总表内容的子集,涉及两个新的SELECT语句子句:GROUP BY子句和HAVING子句
9.1 创建分组
SELECT vend_id, COUNT(*) AS num_prods FROM Products GROUP BY vend_id;/*vend_id num_prodsBRS01 3DLL01 4FNG01 2*//*对每个vend_id进行分组,计算其数量,vend_id为BRS01有3个,vend_id为DLL01有4个*/
- GROUP BY子句的作用于DISTINCT类似
- GROUP BY子句可以按多个item进行分组
- GROUP BY子句常常与汇总函数一起使用
- 如果Value中包含NULL,则NULL将作为一个分组返回
GROUP BY子句必须出现在WHERE子句后,BRDER BY子句前
9.2 过滤分组
使用HAVING子句过滤分组,HAVING和WHERE的作用相同,只是多了可以过滤分组
- WHERE针对特定行,而HAVING基于分组聚集值
- WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤
HAVING和WHERE非常相似,如果不指定GROUP BY,则大多数DBMS会等同对待他们。但使用HAVING时要用GROUP BY
SELECT cust_id, COUNT(*) AS orders FROM Orders GROUP BY cust_id HAVING COUNT(*) >= 2;SELECT cust_id, COUNT(*) AS num_prods FROM Orders WHERE prod_price >= 4 GROUP BY vend_id HAVING COUNT(*) >= 2; /*vend_id num_prods BRS01 3 FNG01 2*/ /*按照vend_id进行分组,且vend_id数量大于等于2,prod_price大于等于4的数据,展示cust_id和vend_id总数*/9.3 分组和排序
| ORDER BY | GROUP BY | | —- | —- | | 对产生的输出排序 | 对行分组,但输出可能不是分组的顺序 | | 任意列都可以使用(甚至非选择的列也可以使用) | 只可能使用选择列或表达式列,而且必须使用每个选择列表达式 | | 不一定需要 | 如果与汇总函数一起使用列,则必须使用 |
一般在使用GROUP BY子句要求排序时,也应该使用ORDER BY子句
SELECT order_num, COUNT(*) AS items FROM OrderItems GROUP BY order_num HAVING COUNT(*) >= 3 ORDER BY item, order_num; /* order_num items 20006 3 20009 3 20007 5 20008 5 */ /*对订单数order_num进行分组,并按照数量,订单号进行排序*/9.4 SELECT子句顺序
| 子句 | 说明 | 是否必须使用 | | —- | —- | —- | | SELECT | 要返回的列或表达式 | 是 | | FROM | 从中检索的表 | 仅在从表选择数据时使用 | | WHERE | 行级过滤 | 否 | | GROUP BY | 分组说明 | 仅在按组计算聚集时使用 | | HAVING | 组级过滤 | 否 | | ORDER BY | 输出排序顺序 | 否 |
