————介绍如何分组数据,以便汇总表内容的子集,涉及两个新的SELECT语句子句:GROUP BY子句和HAVING子句

9.1 创建分组

  1. SELECT vend_id, COUNT(*) AS num_prods FROM Products GROUP BY vend_id;
  2. /*
  3. vend_id num_prods
  4. BRS01 3
  5. DLL01 4
  6. FNG01 2
  7. */
  8. /*对每个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 | 输出排序顺序 | 否 |