排序数据
使用SELECT检索出来的顺序并不是以纯粹的随机顺序显示的, 如果不排序, 数据一般将以它在底层表中出现的顺序显示。这可以是数据最初添加到表的顺序。但是, 如果数据后来进行过更新和删除, 则此顺序将会受到MySQL重用回收存储空间的影响。因此, 如果不明确控制的话, 不能依赖该排序顺序。
关系数据库设计理论认为, 如果不明确规定排序的顺序, 则不应该假定检索出的数据的顺序有意义。
子句:
SQL语句由子句构成, 有些子句是必须的, 而有的是可选的。一个子句通常由一个关键字和所提供的数据组成。
为了明确地排序SELECT语句检索出的数据, 可使用ORDER BY子句。ORDER BY子句取一个或多个列的名字, 据此对输出进行排序。
MariaDB [crashcourse]> 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.006 sec) MariaDB [crashcourse]>
通过非选择列进行排序
通常, ORDER BY子句中使用的列将是为显示所选择的列。但是, 实际上并不一定要这样, 用非检索的列排序是完全合法的
按多个列排序
经常需要不止一个列进行数据排序。为了按多个列排序, 只要指定列名, 列名之间用逗号分开即可。
下面代码检索3个列, 并按其中两个列对结果进行排序--首先按照价格, 然后再按照名称排序。
MariaDB [crashcourse]> 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.000 sec) MariaDB [crashcourse]>
重要的是理解在按多个列排序时, 排序完全按照所规定的顺序进行。
换句话说, 对于上述例子中的输出, 仅在多个行具有相同的prod_price值时才对产品prod_name进行排序。如果prod_price列中所有的值都是唯一的, 那么不会按照prod_name排序。
指定排序方向
MySQL默认的排序方式为升序排序, 可以使用ORDER BY子句以降序排序。为了进行降序排序, 必须指定DESC关键字
MariaDB [crashcourse]> 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 | | TNT2 | 10.00 | TNT (5 sticks) | | FB | 10.00 | Bird seed | | 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.003 sec) MariaDB [crashcourse]>
如果打算以多个列排序, 比如: 以降序排序产品(最贵的在最前面), 然后再对产品名进行排序
MariaDB [crashcourse]> 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.000 sec) MariaDB [crashcourse]>
DESC关键字只作用与直接位于其前面的列名。
在多个列上降序排序
如果想在多个列上进行降序排序, 必须对每个列指定DESC关键字
与DESC想法的是ASC(ASCENDING), 在升序排序时可以指定它。但是升序排序是默认的排序方式。
使用ORDER BY和LIMIT的组合, 可以找到一个列中最高的或最低的值。
MariaDB [crashcourse]> SELECT prod_price FROM products ORDER BY prod_price DESC LIMIT 1; +------------+ | prod_price | +------------+ | 55.00 | +------------+ 1 row in set (0.000 sec) MariaDB [crashcourse]>
ORDER BY子句的位置
在给出ORDER BY子句时, 应该保证它位于FROM子句之后。如果使用LIMIT, 它必须位于ORDER BY之后, 使用子句的次序不对将产生错误的消息