ORDER BY语句用于根据指定的列对结果集进行排序,默认按照升序对结果进行排序。也可显示指定升序(ASC)和降序(DESC)排列。如果select语句没有order by子句,其显示顺序是不可预料的,在select语句末尾添加一个order by子句,只是保证最终结果中的行按照一定的顺序排列。
根据排序的方式不同,可以分为按照列名排序,按照表达式排序,按照顺序号码排序,按照升序和降序排序等。对空值的排序比较特殊,mysql把空值作为最小值对待。
2.1 创建测试表
CREATE TABLE PENALTIES
(PAYMENTNO INTEGER NOT NULL,
PLAYERNO INTEGER NOT NULL,
PAYMENT_DATE DATE NOT NULL,
AMOUNT DECIMAL(7,2) NOT NULL,
PRIMARY KEY (PAYMENTNO));
注:表中记录球员的罚款信息。
2.2 插入测试数据
INSERT INTO PENALTIES VALUES (1, 6, '1980-12-08',100);
INSERT INTO PENALTIES VALUES (2, 44, '1981-05-05', 75);
INSERT INTO PENALTIES VALUES (3, 27, '1983-09-10',100);
INSERT INTO PENALTIES VALUES (4,104, '1984-12-08', 50);
INSERT INTO PENALTIES VALUES (5, 44, '1980-12-08', 25);
INSERT INTO PENALTIES VALUES (6, 8, '1980-12-08', 25);
INSERT INTO PENALTIES VALUES (7, 44, '1982-12-30', 30);
INSERT INTO PENALTIES VALUES (8, 27, '1984-11-12', 75);
3.1 按照列名排序
3.1.1 找出每笔罚款的支付号码和引起罚款的球员号码,并按照球员号码排序。
select paymentno, playerno
from penalties
order by playerno;
注:默认排序为升序,即小的在上面,大的在下面。
3.1.2 如果前面一列包含重复的值,后面一列对应前面重复的值的记录需要排序,也要用order by指定。
例如:对每一笔罚款,获取球员号码和罚款数额,按照这两列的结果进行排序。
select playerno, amount
from penalties
order by playerno, amount;
3.1.3 order by子句可以包含没有出现在select子句中的表达式。
获取所有罚款额,并按照球员号码和罚款额来排序。
select amount
from penalties
order by playerno, amount;
3.2 按照表达式排序
除可以按照列名排序,也可按照标量表达式排序,标量表达式中也可以包含子查询。
例如:对于所有罚款球员,获取所有信息(罚款单号,球员号,罚单时间,罚款额度),并按照罚单时间的年份进行排序。
mysql> select * from penalties
order by substr(payment_date, 1, 4);
3.3 按照顺序号码排序
order by子句中,可以用顺序号码代替由列名或表达式组成的排序。在实际使用中尽量使用列名,避免混淆。
例如对于3.1.1
select paymentno, playerno
from penalties
order by playerno;
执行效果等同于
select paymentno, playerno
from penalties
order by 2;
3.4 使用升序和降序排序
ORDER BY语句默认按照升序对结果进行排序,也可显示指定升序(ASC)和降序(DESC)排列
例如:找出每笔罚款的支付号码和引起罚款的球员号码,并按照球员号码降序排序。
注:对字符的排序还取决于具体字符集和字符集校对。
3.5 对空值排序
排序时mysql把空值当做一列中最小值对待。
在 MySQL 中的ORDER BY有两种排序实现方式,一种是利用有序索引获取有序数据,另一种则是通过相应的排序算法,将取得的数据在内存中进行排序。
4.1 利用有序索引获取有序数据
利用有序索引进行排序,实际上就是当我们 Query 的 ORDER BY 条件和 Query 的执行计划中所利用的 Index 的索引键(或前面几个索引键)完全一致,且索引访问方式为 rang、 ref 或者 index 的时候,MySQL 可以利用索引顺序而直接取得已经排好序的数据。这种方式的 ORDER BY 基本上可以说是最优的排序方式了,因为 MySQL 不需要进行实际的排序操作。
4.2 通过相应的排序算法,将取得的数据在内存中进行排序
通过相应的排序算法,将取得的数据在内存中进行排序方式,MySQL必须要将数据在内存中进行排序,所使用的内存区域也就是我们通过 sort_buffer_size 系统变量所设置的排序区。这个排序区是每个Thread独享的,所以说可能在同一时刻在MySQL中可能存在多个sort buffer内存区域。
第二种方式在MySQL Query Optimizer所给出的执行计划(通过EXPLAIN命令查看)中被称为filesort。在这种方式中,主要是由于没有可以利用的有序索引取得有序的数据,MySQL只能通过将取得的数据在内存中进行排序然后再将数据返回给客户端。在MySQL中filesort的实现算法实际上是有两种的,一种是首先根据相应的条件取出相应的排序字段和可以直接定位行数据的行指针信息,然后在sort buffer中进行排序。另外一种是一次性取出满足条件行的所有字段,然后在sort buffer中进行排序。
5.1 group by 比order by先执行,order by不会对group by 内部进行排序,如果group by后只有一条记录,那么order by 将无效。要查出group by中最大的或最小的某一字段使用 max或min函数。
原文地址: http://blog.csdn.net/jesseyoung/article/details/40183059
博客主页: http://blog.csdn.net/jesseyoung
****************************************************************************************