十三、分组数据
01. 数据分组
目前为止的所有计算都是在表的所有数据或匹配特定的WHERE子句的数据上进行的:返回供应商1003提供的产品数目
如果要返回每个供应商提供的产品数目怎么办?或者返回只提供单项产品的供应商所提供的产品,或返回提供10个以上产品的供应商怎么办?
02. 创建分组
分组是在SELECT语句的GROUP BY子句中建立的:
- GROUP BY子句指示MySQL按vend_id排序并分组数据,这导致对每个vend_id而不是整个表计算num_prods一次;
- GROUP BY子句指示MySQL分组数据,然后对每个组而不是整个结果集进行聚集;
- 在具体使用GROUP BY子句前,需要知道一些重要的规定:
3.1 可以包含任意数目的列;
3.2 在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上进行汇总;
3.3 列出的每个列都必须是检索列或有效的表达式(但不能是聚集函数),如果在SELECT中使用表达式,则必须在GROUP BY子句中指定相同的表达式,不能使用别名;
3.4 除聚集计算语句外,SELECT语句中的每个列都必须在GROUP BY子句中给出;
3.5 如果分组列中具有NULL值,则NULL将作为一个分组返回,如果列中有多行NULL值,它们将分为一组;
3.6 GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。
03. 过滤分组
除了能用GROUP BY分组数据外,MySQL还允许过滤分组,规定包括哪些分组,排除哪些分组。例如,可能想要列出至少有两个订单的所有顾客:
- HAVING非常类似于WHERE;
- 目前为止所学过的所有类型的WHERE子句都可以用HAVING来替代;
- 唯一的差别是WHERE过滤行,而HAVING过滤分组;
- 另一种理解方法,WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤;
- 同时使用WHERE和HAVING子句:
5.1 列出具有2个(含)以上、价格为10(含)以上的产品的供应商;
5.2 如果没有WHERE子句,将会多检索出两行(供应商1002,销售的所有产品价格都在10以下;供应商1001,销售3个产品,但只有一个产品的价格大于等于10)。
04. 分组和排序
GROUP BY和ORDER BY之间的差别:
一般在使用GROUP BY子句时,应该也给出ORDER BY子句。这是保证数据正确排序的唯一方法,千万不要仅依赖GROUP BY排序数据。
- 检索总计订单价格大于等于50的订单的订单号和总计订单价格:
- 按总计订单价格排序输出,需要添加ORDER BY子句:
05. SELECT子句顺序
在SELECT语句中使用时必须遵循的次序: