Skip to content

sql-order-by

SQL ORDER BY 子句用于根据一个或多个列中的值对结果集中的行进行排序。如果没有 ORDER BY 子句,关系型数据库系统不保证返回行的任何特定顺序。如果您需要结果以可预测的顺序呈现,则必须使用 ORDER BY。

ORDER BY 在 SELECT 语句的末尾指定,位于 FROM、WHERE、GROUP BY 和 HAVING 子句之后。

SELECT column_list
FROM table_name
[WHERE condition]
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...;
  • ASC: 以升序(A 到 Z,0 到 9)对结果进行排序。如果未指定排序,这是默认行为。
  • DESC: 以降序(Z 到 A,9 到 0)对结果进行排序。

对于我们的示例,我们使用 EMPLOYEES 表。

CREATE TABLE EMPLOYEES (
ID INT PRIMARY KEY,
FIRST_NAME VARCHAR(50) NOT NULL,
LAST_NAME VARCHAR(50) NOT NULL,
DEPARTMENT VARCHAR(50),
SALARY DECIMAL(10, 2)
);
INSERT INTO EMPLOYEES VALUES
(1, 'Alice', 'Smith', 'Engineering', 90000.00),
(2, 'Bob', 'Johnson', 'Engineering', 85000.00),
(3, 'Charlie', 'Brown', 'Marketing', 70000.00),
(4, 'Diana', 'Prince', 'Marketing', 72000.00),
(5, 'Ethan', 'Hunt', NULL, 110000.00);

这是最简单的排序形式,基于单个列。

SELECT FIRST_NAME, LAST_NAME, SALARY FROM EMPLOYEES
ORDER BY SALARY DESC;

此查询将员工从薪资最高到最低列出。

您可以按多列排序。数据库首先按指定的第一列对结果进行排序。然后,对于在第一列中具有相同值的任何行,它会按第二列进行排序,依此类推。

示例:先按部门排序,再按薪资排序

Section titled “示例:先按部门排序,再按薪资排序”
SELECT FIRST_NAME, DEPARTMENT, SALARY FROM EMPLOYEES
ORDER BY DEPARTMENT ASC, SALARY DESC;

此查询将首先按部门(按字母顺序)对员工进行分组,然后在每个部门内部,将他们从最高薪资到最低薪资列出。

FIRST_NAMEDEPARTMENTSALARY
AliceEngineering90000.00
BobEngineering85000.00
DianaMarketing72000.00
CharlieMarketing70000.00
Ethan110000.00

NULL 值的排序方式取决于数据库系统。有些系统将 NULL 值放在前面,有些则放在后面。标准 SQL 提供了 NULLS FIRST 和 NULLS LAST 选项以进行显式控制(PostgreSQL 和 Oracle 支持)。

-- 列出部门,确保 NULL 值出现在末尾
SELECT DEPARTMENT FROM EMPLOYEES
ORDER BY DEPARTMENT ASC NULLS LAST;

在 MySQL 和 SQL Server 中,您可以通过 CASE 语句或对于数值类型使用 ORDER BY -column DESC 这样的技巧来实现。

有时您需要根据非标准、业务定义的顺序进行排序。ORDER BY 中的 CASE 语句非常适合此目的。

SELECT FIRST_NAME, DEPARTMENT FROM EMPLOYEES
ORDER BY
CASE DEPARTMENT
WHEN 'Engineering' THEN 1
WHEN 'Marketing' THEN 2
ELSE 3
END;

此查询强制“Engineering”排在第一位,其次是“Marketing”,然后是所有其他部门。

排序可能是一个资源密集型操作,尤其是在大型表上。通过在您排序的列上创建数据库索引可以显著提高性能。

专业提示: 如果带有 ORDER BY 的查询很慢,优化的第一步是检查排序列上是否存在索引。对于 ORDER BY a, b 这样的多列排序,在 (a, b) 上创建复合索引是最有效的。

-- 这个索引将加速我们的多列排序示例
CREATE INDEX idx_employees_dept_salary ON EMPLOYEES (DEPARTMENT, SALARY);