🙏 我们需要您的帮助!SQLtest.online 没有广告,完全依靠捐款运行。哪怕一点点也很有帮助。 立即捐助 →
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 的默认排序方向是什么?

MySQL

  1. 有序电影标题
  2. 有序语言列表
  3. 获取客户列表

SQLite

  1. 排序企鹅
  2. 企鹅物种在岛屿上的分布
  3. 鳍长与体重比率

PostgreSQL

  1. 获取机场数据
  2. 机场列表
  3. 显示机场表

SQL Server

  1. 列出唯一客户
  2. 产品列表

Firebird

  1. 列出部门

MariaDB

  1. 学生入学年龄