排序检索数据
本章将讲授如何使用SELECT语句的ORDER BY子句,根据需要排序检索数据。
排序数据
下面SQL语句返回数据库的单列,但输出没有特定的顺序:
mysql> SELECT prod_name
-> FROM products;
+----------------+
| prod_name |
+----------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
| Detonator |
| Bird seed |
| Carrots |
| Fuses |
| JetPack 1000 |
| JetPack 2000 |
| Oil can |
| Safe |
| Sling |
| TNT (1 stick) |
| TNT (5 sticks) |
+----------------+
14 rows in set (0.02 sec)
检索出的数据并不是纯粹的随机顺序。如果不排序,数据一般以底层表中出现的顺序显示(数据添加到表的顺序)。但底层表数据顺序会被数据更新或删除影响。所以如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有意义。
子句(clause) SQL语句由子句构成,有些子句必须,而有些子句可选。一个子句通常由一个关键字和所提供的数据组成。
为了明确地排序用SELECT语句检索出的数据,可以使用ORDER BY子句。
ORDER BY子句取一个或多个列的名字,据此对输出进行排序。
mysql> SELECT prod_name
-> FROM products
-> ORDER BY prod_name;
+----------------+
| prod_name |
+----------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
| Bird seed |
| Carrots |
| Detonator |
| Fuses |
| JetPack 1000 |
| JetPack 2000 |
| Oil can |
| Safe |
| Sling |
| TNT (1 stick) |
| TNT (5 sticks) |
+----------------+
14 rows in set (0.01 sec)
这条语句使用ORDER BY语句指示MySQL对prod_name列以字母顺序排序数据,其他与上个例子相同。
- 通过非选择列进行排序 通常,ORDER BY子句中使用的列是结果显示列。但也可以不使用结果列中的列进行排序。
按多个列排序
我们排序经常需要按不止一个列进行数据排序。例如按名字排序需要先按姓排序后按名排序。
为了按多个列排序,只需指定列名,列名间用逗号分开(同选择多个行那样)。
下面代码检索三个列,并按两个列对结果排序(先按价格排序,后按名称排序)。
mysql> SELECT prod_id, prod_price, prod_name
-> FROM products
-> ORDER BY prod_price, prod_name;
+---------+------------+----------------+
| prod_id | prod_price | prod_name |
+---------+------------+----------------+
| FC | 2.50 | Carrots |
| TNT1 | 2.50 | TNT (1 stick) |
| FU1 | 3.42 | Fuses |
| SLING | 4.49 | Sling |
| ANV01 | 5.99 | .5 ton anvil |
| OL1 | 8.99 | Oil can |
| ANV02 | 9.99 | 1 ton anvil |
| FB | 10.00 | Bird seed |
| TNT2 | 10.00 | TNT (5 sticks) |
| DTNTR | 13.00 | Detonator |
| ANV03 | 14.99 | 2 ton anvil |
| JP1000 | 35.00 | JetPack 1000 |
| SAFE | 50.00 | Safe |
| JP2000 | 55.00 | JetPack 2000 |
+---------+------------+----------------+
14 rows in set (0.00 sec)
注意:按多个列排序时,排序完全按所规定的顺序进行。类似于按顺序成组排序,每次排序都是在组内排序,例如若prod_price没有重复的值(即每行自成一组),那再按prod_name排序将对结果无影响(每组只有一条记录)。
指定排序方向
数据排序不限于升序排序(从A到Z)。这只是默认排序顺序,还可以通过DESC关键词进行降序排序。
按价格以降序排序产品(最贵的在前面):
mysql> SELECT prod_id, prod_price, prod_name
-> FROM products
-> ORDER BY prod_price DESC;
+---------+------------+----------------+
| prod_id | prod_price | prod_name |
+---------+------------+----------------+
| JP2000 | 55.00 | JetPack 2000 |
| SAFE | 50.00 | Safe |
| JP1000 | 35.00 | JetPack 1000 |
| ANV03 | 14.99 | 2 ton anvil |
| DTNTR | 13.00 | Detonator |
| FB | 10.00 | Bird seed |
| TNT2 | 10.00 | TNT (5 sticks) |
| ANV02 | 9.99 | 1 ton anvil |
| OL1 | 8.99 | Oil can |
| ANV01 | 5.99 | .5 ton anvil |
| SLING | 4.49 | Sling |
| FU1 | 3.42 | Fuses |
| FC | 2.50 | Carrots |
| TNT1 | 2.50 | TNT (1 stick) |
+---------+------------+----------------+
14 rows in set (0.00 sec)
对多个列排序时,只需对需要降序的列后添加DESC关键字:
mysql> SELECT prod_id, prod_price, prod_name
-> FROM products
-> ORDER BY prod_price DESC, prod_name;
+---------+------------+----------------+
| prod_id | prod_price | prod_name |
+---------+------------+----------------+
| JP2000 | 55.00 | JetPack 2000 |
| SAFE | 50.00 | Safe |
| JP1000 | 35.00 | JetPack 1000 |
| ANV03 | 14.99 | 2 ton anvil |
| DTNTR | 13.00 | Detonator |
| FB | 10.00 | Bird seed |
| TNT2 | 10.00 | TNT (5 sticks) |
| ANV02 | 9.99 | 1 ton anvil |
| OL1 | 8.99 | Oil can |
| ANV01 | 5.99 | .5 ton anvil |
| SLING | 4.49 | Sling |
| FU1 | 3.42 | Fuses |
| FC | 2.50 | Carrots |
| TNT1 | 2.50 | TNT (1 stick) |
+---------+------------+----------------+
14 rows in set (0.00 sec)
DESC关键字只应用于位于其前面的列名。上个例子只对prod_price降序,而prod_name还是升序排序。
与DESC相反的关键字是ASC(ASCENDING),可以用它来指定升序排序。但ASC没多大用,因为升序是默认的。
使用ORDER BY和LIMIT的组合,可以找出一个列中最大或最小的值:
mysql> SELECT prod_price
-> FROM products
-> ORDER BY prod_price DESC
-> LIMIT 1;
+------------+
| prod_price |
+------------+
| 55.00 |
+------------+
1 row in set (0.00 sec)
prod_price DESC保证行是从最贵到最便宜,LIMIT 1告诉MySQL返回一行。
- 在多个列上降序排序 如果想在多个列上降序排序,那需要对每个列都指定DESC关键字。
- 区分大小写和排序顺序 对文本性的数据进行排序时,一般按字典(dictionary)序,不区分大小写,a等同于A。若想改变排序规则,请联系数据库管理员。
- ORDER BY子句的位置 在给出ORDER BY子句时,必须保证它在FROM子句后。而LIMIT子句必须位于ORDER BY子句后。顺序不对将产生错误信息。