MySQL ORDER BY

摘要:在本教程中,您将学习如何使用 MySQL ORDER BY子句对结果集中的行进行排序。

MySQL ORDER BY 子句简介

当您使用SELECT语句从表中查询数据时,结果集中的行顺序是未指定的。要对结果集中的行进行排序,请将ORDER BY子句添加到SELECT语句中。

下面说明了ORDER BY子句的语法:

SELECT 
   select_list
FROM 
   table_name
ORDER BY 
   column1 [ASC|DESC], 
   column2 [ASC|DESC],
   ...;Code language: SQL (Structured Query Language) (sql)

在此语法中,您可以在ORDER BY子句之后指定要排序的一列或多列。

ASC代表上升, DESC代表下降。分别使用ASC对结果集进行升序排序, DESC对结果集进行降序排序。

ORDER BY子句按column1中的值按升序对结果集进行排序:

ORDER BY column1 ASC;Code language: SQL (Structured Query Language) (sql)

ORDER BY子句按column1中的值按降序对结果集进行排序:

ORDER BY column1 DESC;Code language: SQL (Structured Query Language) (sql)

默认情况下,如果您未显式指定任何选项, ORDER BY子句将使用ASC 。因此,以下ORDER BY子句是等效的:

ORDER BY column1 ASC;Code language: SQL (Structured Query Language) (sql)

ORDER BY column1;Code language: SQL (Structured Query Language) (sql)

如果要按多列对结果集进行排序,请在ORDER BY子句中指定以逗号分隔的列列表:

ORDER BY
   column1,
   column2;Code language: SQL (Structured Query Language) (sql)

在这种情况下, ORDER BY子句首先对结果集按column1升序排序,然后对排序后的结果集按column2升序排序。

可以按一列按升序对结果集进行排序,然后按另一列按降序排序:

ORDER BY
    column1 ASC,
    column2 DESC;Code language: SQL (Structured Query Language) (sql)

在这种情况下, ORDER BY子句:

  • 首先,按column1中的值按升序对结果集进行排序。
  • 然后,将排序后的结果集按照column2中的值进行降序排序。请注意,在此步骤中, column1中的值的顺序不会更改,仅column2中的值的顺序会更改。

当执行带有ORDER BY子句SELECT语句时,MySQL 总是在FROMSELECT子句之后计算ORDER BY子句:

MySQL ORDER BY 示例

我们将使用示例数据库中的customers表进行演示。

A) 使用 MySQL ORDER BY 子句对结果集按一列进行排序示例

以下查询使用ORDER BY子句按客户的姓氏升序对客户进行排序。

SELECT
	contactLastname,
	contactFirstname
FROM
	customers
ORDER BY
	contactLastname;Code language: SQL (Structured Query Language) (sql)

试试看

输出:

+-----------------+------------------+
| contactLastname | contactFirstname |
+-----------------+------------------+
| Accorti         | Paolo            |
| Altagar,G M     | Raanan           |
| Andersen        | Mel              |
| Anton           | Carmen           |
| Ashworth        | Rachel           |
| Barajas         | Miguel           |
...Code language: plaintext (plaintext)

如果要按姓氏降序对客户进行排序,请在ORDER BY子句中的contactLastname列后使用DESC ,如以下查询所示:

SELECT
	contactLastname,
	contactFirstname
FROM
	customers
ORDER BY
	contactLastname DESC;Code language: SQL (Structured Query Language) (sql)

试试看

输出:

+-----------------+------------------+
| contactLastname | contactFirstname |
+-----------------+------------------+
| Young           | Jeff             |
| Young           | Julie            |
| Young           | Mary             |
| Young           | Dorothy          |
| Yoshido         | Juri             |
| Walker          | Brydey           |
| Victorino       | Wendy            |
| Urs             | Braun            |
| Tseng           | Jerry            |
....Code language: plaintext (plaintext)

B) 使用 MySQL ORDER BY 子句对结果集按多列排序示例

如果要按姓氏降序对客户进行排序,然后按名升序对客户进行排序,请在这些相应的列中同时指定DESCASC ,如下所示:

SELECT 
    contactLastname, 
    contactFirstname
FROM
    customers
ORDER BY 
	contactLastname DESC , 
	contactFirstname ASC;Code language: SQL (Structured Query Language) (sql)

试试看

输出:

+-----------------+------------------+
| contactLastname | contactFirstname |
+-----------------+------------------+
| Young           | Dorothy          |
| Young           | Jeff             |
| Young           | Julie            |
| Young           | Mary             |
| Yoshido         | Juri             |
| Walker          | Brydey           |
| Victorino       | Wendy            |
| Urs             | Braun            |
| Tseng           | Jerry            |
| Tonini          | Daniel           |
...Code language: plaintext (plaintext)

在本示例中, ORDER BY子句先将结果集按姓氏降序排序,然后将排序后的结果集按名升序排序,得到最终的结果集。

C) 使用 MySQL ORDER BY 子句按表达式对结果集进行排序示例

请参阅示例数据库中的以下orderdetails表。

订单详情表

以下查询从orderdetails表中选择订单行项目。它计算每个行项目的小计,并根据小计对结果集进行排序。

SELECT 
    orderNumber, 
    orderlinenumber, 
    quantityOrdered * priceEach
FROM
    orderdetails
ORDER BY 
   quantityOrdered * priceEach DESC;Code language: SQL (Structured Query Language) (sql)

试试看

+-------------+-----------------+-----------------------------+
| orderNumber | orderlinenumber | quantityOrdered * priceEach |
+-------------+-----------------+-----------------------------+
|       10403 |               9 |                    11503.14 |
|       10405 |               5 |                    11170.52 |
|       10407 |               2 |                    10723.60 |
|       10404 |               3 |                    10460.16 |
|       10312 |               3 |                    10286.40 |
...Code language: plaintext (plaintext)

为了使查询更具可读性,您可以为SELECT子句中的表达式分配一个列别名,并在ORDER BY子句中使用该列别名,如以下查询所示:

SELECT 
    orderNumber,
    orderLineNumber,
    quantityOrdered * priceEach AS subtotal
FROM
    orderdetails
ORDER BY subtotal DESC;Code language: SQL (Structured Query Language) (sql)

试试看

+-------------+-----------------+----------+
| orderNumber | orderLineNumber | subtotal |
+-------------+-----------------+----------+
|       10403 |               9 | 11503.14 |
|       10405 |               5 | 11170.52 |
|       10407 |               2 | 10723.60 |
|       10404 |               3 | 10460.16 |
|       10312 |               3 | 10286.40 |
|       10424 |               6 | 10072.00 |
|       10348 |               8 |  9974.40 |
|       10405 |               3 |  9712.04 |
|       10196 |               5 |  9571.08 |
|       10206 |               6 |  9568.73 |
 ...Code language: plaintext (plaintext)

在此示例中,我们使用subtotal作为表达式quantityOrdered * priceEach列别名,并按subtotal别名对结果集进行排序。

由于 MySQL 在ORDER BY子句之前评估SELECT子句,因此您可以在ORDER BY子句中使用SELECT子句中指定的列别名。

使用 MySQL ORDER BY 子句使用自定义列表对数据进行排序

FIELD()函数具有以下语法:

FIELD(str, str1, str2, ...)Code language: SQL (Structured Query Language) (sql)

FIELD()函数返回 str 在 str1、str2、... 列表中的位置。如果 str 不在列表中,则FIELD()函数返回 0。例如,以下查询返回 1,因为字符串 'A' 的位置是列表'A''B'中的第一个位置'C'

SELECT FIELD('A', 'A', 'B','C');Code language: SQL (Structured Query Language) (sql)

输出:

+--------------------------+
| FIELD('A', 'A', 'B','C') |
+--------------------------+
|                        1 |
+--------------------------+
1 row in set (0.00 sec)Code language: plaintext (plaintext)

以下示例返回 2:

SELECT FIELD('B', 'A','B','C');Code language: SQL (Structured Query Language) (sql)

输出:

+-------------------------+
| FIELD('B', 'A','B','C') |
+-------------------------+
|                       2 |
+-------------------------+
1 row in set (0.00 sec)Code language: plaintext (plaintext)

让我们举一个更实际的例子。

请参阅示例数据库中的以下orders表。

订单表

假设您要根据销售订单的状态按以下顺序对销售订单进行排序:

  • 处理中
  • 等候接听
  • 取消
  • 解决
  • 争议
  • 已发货

为此,您可以使用FIELD()函数将每个订单状态映射到一个数字,并按FIELD()函数的结果对结果进行排序:

SELECT 
    orderNumber, status
FROM
    orders
ORDER BY FIELD(status,
        'In Process',
        'On Hold',
        'Cancelled',
        'Resolved',
        'Disputed',
        'Shipped');Code language: SQL (Structured Query Language) (sql)

试试看

+-------------+------------+
| orderNumber | status     |
+-------------+------------+
|       10425 | In Process |
|       10421 | In Process |
|       10422 | In Process |
|       10420 | In Process |
|       10424 | In Process |
|       10423 | In Process |
|       10414 | On Hold    |
|       10401 | On Hold    |
|       10334 | On Hold    |
|       10407 | On Hold    |
...Code language: plaintext (plaintext)

MySQL ORDER BY 和 NULL

在 MySQL 中, NULL位于非 NULL 值之前。因此,当您使用带有ASC选项的ORDER BY子句时, NULLs将首先出现在结果集中。

例如,以下查询使用ORDER BY子句按reportsTo列中的值对员工进行排序:

SELECT 
    firstName, lastName, reportsTo
FROM
    employees
ORDER BY reportsTo;Code language: SQL (Structured Query Language) (sql)

输出:

+-----------+-----------+-----------+
| firstName | lastName  | reportsTo |
+-----------+-----------+-----------+
| Diane     | Murphy    |      NULL |
| Mary      | Patterson |      1002 |
| Jeff      | Firrelli  |      1002 |
| William   | Patterson |      1056 |
| Gerard    | Bondur    |      1056 |
...Code language: plaintext (plaintext)

但是,如果将ORDER BYDESC选项一起使用, NULLs将出现在结果集中的最后。例如:

SELECT 
    firstName, lastName, reportsTo
FROM
    employees
ORDER BY reportsTo DESC;Code language: SQL (Structured Query Language) (sql)

输出:

+-----------+-----------+-----------+
| firstName | lastName  | reportsTo |
+-----------+-----------+-----------+
| Yoshimi   | Kato      |      1621 |
| Leslie    | Jennings  |      1143 |
| Leslie    | Thompson  |      1143 |
| Julie     | Firrelli  |      1143 |
| ....
| Mami      | Nishi     |      1056 |
| Mary      | Patterson |      1002 |
| Jeff      | Firrelli  |      1002 |
| Diane     | Murphy    |      NULL |
+-----------+-----------+-----------+
23 rows in set (0.00 sec)Code language: plaintext (plaintext)

概括

  • 使用ORDER BY子句按一列或多列对结果集进行排序。
  • 使用ASC选项按升序对结果集进行排序,使用DESC选项按降序对结果集进行排序。
  • ORDER BY子句在FROMSELECT子句之后计算。
  • 在 MySQL 中, NULL低于非 NULL 值
本教程有帮助吗?