🎯 本月只剩几天支持 SQLTest.online,帮助我们让 SQL 练习对每个人都免费。 今天捐赠 →
SQL 代码已复制到剪贴板

SQL ORDER BY:对查询结果排序

第 2.6 课 · 阅读时间:约 6 分钟 · 练习题 ↓

SQL ORDER BY 子句按一个或多个列或表达式对查询结果的行进行排序。在本课中,你将学习升序和降序排序、按多列排序、按表达式和别名排序,以及 NULL 值的排序方式。

表本身没有内置的行顺序。没有 ORDER BY 时,数据库会按照对它最方便的顺序返回行,而且每次运行的顺序都可能不同。只要顺序很重要-例如报表、排行榜或按时间排列的日志-就必须明确指定。

SQL ORDER BY:升序和降序排序,按多列排序时由下一列区分相同值,以及 NULL 值的位置

ORDER BY 子句

ORDER BY 写在 SELECT 语句的末尾,列出排序键。

基本语法

SELECT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...;
  • ASC 按升序排序:从小到大、从 A 到 Z、从早到晚。这是默认顺序。
  • DESC 按降序排序。

按单列排序

SELECT first_name, last_name
FROM actor
ORDER BY last_name;

结果:所有演员按姓氏的字母顺序排列。

要反转顺序,请添加 DESC:

SELECT title, length
FROM film
ORDER BY length DESC;

结果:电影从最长到最短排列。


按多列排序

当第一个排序键的值相同时,数据库使用第二个排序键对这些行排序,然后是第三个,依此类推:

SELECT first_name, last_name
FROM actor
ORDER BY last_name, first_name;

结果:演员按姓氏排序;姓氏相同的演员再按名字排序。

每一列都有自己的排序方向。ASC 或 DESC 只作用于它前面的那一列:

SELECT title, rating, length
FROM film
ORDER BY rating, length DESC;

结果:电影按分级分组;在每个分级内,最长的电影排在最前面。


按表达式排序

你不仅可以按存储的列排序,也可以按计算出的值排序。表达式会针对每一行计算,然后按结果对行排序:

SELECT title, rental_rate, rental_duration
FROM film
ORDER BY rental_rate * rental_duration DESC;

结果:电影按整个租期的租赁费用排序,最贵的排在最前面。

比较运算也可以作为排序键,这便于把某些行放到最上面:

SELECT title, rating
FROM film
ORDER BY rating = 'G' DESC, title;

结果:分级为 G 的电影排在最上面,然后是其他所有电影;每组内按片名排序。

在 MySQL 和 MariaDB 中,比较运算返回 1 或 0,因此 DESC 会把匹配的行排在前面。并非所有数据库都能按比较运算排序;可移植的写法使用 CASE,你将在第 3.5 课中学习。


按别名和列位置排序

ORDER BY 在 SELECT 之后处理,因此可以使用在 SELECT 中定义的列别名:

SELECT title, rental_rate * rental_duration AS full_rental_cost
FROM film
ORDER BY full_rental_cost DESC;

也可以按列在 SELECT 列表中的位置排序:

SELECT first_name, last_name
FROM actor
ORDER BY 2, 1;

结果:演员先按第二列(last_name)排序,再按第一列(first_name)排序。

按位置排序在临时查询中很方便,但当有人修改列列表时,它会悄无声息地失效。在需要保存的查询中,请使用列名或别名。


排序与 NULL 值

NULL 表示“没有值”,因此数据库必须决定把这些行放在哪里。在 MySQL、MariaDB 和 SQL Server 中,升序时 NULL 值排在最前面,降序时排在最后。PostgreSQL 和 Oracle 则相反。

SELECT rental_id, rental_date, return_date
FROM rental
ORDER BY return_date
LIMIT 10;

结果:在 MySQL 中,尚未归还的租赁(return_date 为 NULL)排在最前面。


要点:

  • 没有 ORDER BY,结果中行的顺序就没有保证。
  • ASC(默认)按升序排序,DESC 按降序排序。
  • 有多个排序键时,每个后续键对前一个键相同的行进行排序。
  • ASC 和 DESC 分别作用于每一列。
  • 可以按表达式、别名和列位置排序;列名和别名比位置更可靠。
  • NULL 值出现的位置取决于数据库。

常见问题

SQL 默认的排序顺序是什么?

升序(ASC)。ORDER BY last_name 和 ORDER BY last_name ASC 返回相同的结果。

如何按多列以不同方向排序?

在每一列后面写出方向:ORDER BY rating ASC, length DESC。排序方向只作用于它前面的列。

可以在 ORDER BY 中使用列别名吗?

可以。ORDER BY 在 SELECT 之后处理,所以 SELECT 列表中定义的别名在这里可用。这一点与 WHERE 不同,WHERE 中不能使用别名。

尝试解决以下任务,以巩固您在本课中学到的内容。

  1. ORDER BY 的默认排序方向是什么?
  2. 有序电影标题
  3. 有序语言列表
  4. 获取客户列表
  5. 获取机场数据