10.4 分组和排序
GROUP BY
和ORDER BY
经常完成相同的工作,但它们非常不同,理解这一点很重要。表10-1汇总了它们之间的差别。
表10-1 ORDER BY与GROUP BY
ORDER BY | GROUP BY |
---|---|
对产生的输出排序 | 对行分组,但输出可能不是分组的顺序 |
任意列都可以使用(甚至非选择的列也可以使用) | 只可能使用选择列或表达式列,而且必须使用每个选择列表达式 |
不一定需要 | 如果与聚集函数一起使用列(或表达式),则必须使用 |
表10-1中列出的第一项差别极为重要。我们经常发现,用GROUP BY
分组的数据确实是以分组顺序输出的。但并不总是这样,这不是SQL规范所要求的。此外,即使特定的DBMS总是按给出的GROUP BY
子句排序数据,用户也可能会要求以不同的顺序排序。就因为你以某种方式分组数据(获得特定的分组聚集值),并不表示你需要以相同的方式排序输出。应该提供明确的ORDER BY
子句,即使其效果等同于GROUP BY
子句。
提示:不要忘记
ORDER BY
一般在使用GROUP BY
子句时,应该也给出ORDER BY
子句。这是保证数据正确排序的唯一方法。千万不要仅依赖GROUP BY
排序数据。
为说明GROUP BY
和ORDER BY
的使用方法,来看一个例子。下面的SELECT
语句类似于前面那些例子。它检索包含三个或更多物品的订单号和订购物品的数目:
输入▼
SELECT order_num, COUNT(*) AS items
FROM OrderItems
GROUP BY order_num
HAVING COUNT(*) >= 3;
输出▼
order_num items
--------- -----
20006 3
20007 5
20008 5
20009 3
要按订购物品的数目排序输出,需要添加ORDER BY
子句,如下所示:
输入▼
SELECT order_num, COUNT(*) AS items
FROM OrderItems
GROUP BY order_num
HAVING COUNT(*) >= 3
ORDER BY items, order_num;
说明:Access的不兼容性
Microsoft Access不允许按别名排序,因此这个例子在Access中将失败。解决方法是用实际的计算或字段位置替换items
(在ORDER BY
子句中),即ORDER BY COUNT(*), order_num
或ORDER BY 2, order_num
。
输出▼
order_num items
--------- -----
20006 3
20009 3
20007 5
20008 5
分析▼
在这个例子中,使用GROUP BY
子句按订单号(order_num
列)分组数据,以便COUNT(*)
函数能够返回每个订单中的物品数目。HAVING
子句过滤数据,使得只返回包含三个或更多物品的订单。最后,用ORDER BY
子句排序输出。