🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

ORDER BY基础:如何使用SQL自由排序数据

网站上的商品列表、博客文章目录、用户排行榜……我们日常所见的许多网页内容,都是按照某种规则进行排序的。而这种数据的排序,就是通过SQL中的 ORDER BY 子句 实现的。

本文面向刚开始学习SQL的网页开发者,或是想重新复习基础的朋友,全面讲解ORDER BY的使用方法。以“复制粘贴即可运行!”为主题,我们准备了大量示例代码。动手试一试,体验自由操控数据的乐趣吧!


先从准备开始!创建示例数据

与其死记硬背,不如动手实践!我们马上来写SQL代码。本文以虚构的在线杂货商店“Web Creator's Mart”的商品表(products)为例进行说明。

以下SQL语句用于创建该表并插入示例数据。后续代码都基于该表已存在的前提进行说明,因此如果你想在自己的环境中尝试,请先执行以下SQL。

-- 创建商品表
CREATE TABLE products (
  id INT,
  name VARCHAR(255),
  category VARCHAR(255),
  price INT,
  release_date DATE
);

-- 插入示例数据
INSERT INTO products (id, name, category, price, release_date) VALUES
(1, '毛绒靠垫', '家居', 3200, '2023-04-15'),
(2, '专注耳罩', '数码产品', 7800, '2023-11-01'),
(3, '灵感笔记本', '文具', 1200, '2022-08-20'),
(4, '发光键盘', '数码产品', 15000, '2023-06-30'),
(5, '超舒适座椅', '家居', 32000, '2022-11-10'),
(6, '顺滑圆珠笔', '文具', 1200, '2023-09-01'),
(7, '创作者马克杯', '餐具', 2500, '2023-04-15');

该表包含商品ID(id)、商品名称(name)、类别(category)、价格(price)和发布日期(release_date)等字段。准备好了吗?接下来我们就来使用ORDER BY吧!


ORDER BY基础:先从升序排列开始

ORDER BY最基本的用法是按照某个字段的值进行升序排列(从小到大,从旧到新)。例如,你想根据价格从低到高显示商品列表时,就可以使用它。

语法非常简单,只需要在 SELECT 语句的末尾添加 ORDER BY 字段名 即可。

SELECT * FROM products ORDER BY price;

执行该SQL语句后,数据将根据 price 列按升序(从小到大)排序。顺便说一下,ASC(Ascending 的缩写)用于明确指定升序排列,但由于 ORDER BY 默认就是升序,一般可以省略 ASC

-- 和上面的代码效果完全相同
SELECT * FROM products ORDER BY price ASC;

反向排序也很简单!使用 DESC 进行降序排列

有时你可能希望数据按照相反顺序排序,例如“价格从高到低”或“发布日期从新到旧”。这种情况下就要使用 降序(从大到小 / 从新到旧),这就需要用到 DESC(Descending 的缩写)。

只需在列名后加上 DESC,就可以实现降序排序,非常简单!

-- 按价格从高到低排序
SELECT * FROM products ORDER BY price DESC;

此查询会将最贵的商品 “超舒适座椅” 排在最前面。你也可以根据发布日期 (release_date) 从新到旧排序。

-- 按发布日期从新到旧排序
SELECT * FROM products ORDER BY release_date DESC;

ASC 是可选的,但如果想要降序排列,必须加上 DESC,请不要忘记。


进阶用法①:使用多个条件排序

ORDER BY 的一个强大之处在于可以按多个条件组合排序。例如你想要 先按类别排序,再在同一类别内按价格升序排列

这时你只需在 ORDER BY 子句中用逗号(,)分隔多个列名即可。前面的列是排序的主要关键字。

-- 先按类别升序,再按价格升序排序
SELECT * FROM products ORDER BY category, price;

执行这条语句后,商品会首先按照 category(类别)按字母顺序排序(如:Gadget → Interior → Stationery...),然后在“文具”类别内,按 price(价格)升序排列。

当然,每一列也可以分别指定升序或降序。例如:先按发布日期从新到旧排序,再在同一天的商品中按价格从高到低显示,这是电商常见的排序逻辑。

-- 先按发布日期降序,再按价格降序排序
SELECT * FROM products ORDER BY release_date DESC, price DESC;

在示例数据中,“毛绒靠垫”与“创作者马克杯”具有相同的发布日期(2023-04-15),执行上述SQL后,价格更高的“毛绒靠垫”将排在前面。掌握多条件排序可以让数据展示更灵活、更专业!


💻 来试试吧!直接在浏览器中执行 SQL

看到这里你已经了解了很多 SQL 示例,不过最好的学习方式就是动手实践。
因此,我们为你准备了一个可以在浏览器中直接运行 SQL 的 HTML 文件,无需任何安装!

只需将下方代码全部复制,保存为 index.html 文件并用浏览器打开,你就拥有了一个专属的 SQL 练习平台。赶紧试试本文介绍的各种 ORDER BY 用法吧!

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ORDER BY SQL 在线练习工具</title>
  <style>
    body { font-family: sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 2rem auto; padding: 0 1rem; }
    h1, h2 { color: #444; }
    textarea { width: 100%; height: 150px; font-family: monospace; font-size: 16px; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }
    button { background-color: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }
    button:hover { background-color: #0056b3; }
    #result-container { margin-top: 1.5rem; }
    table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
    th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
    th { background-color: #f2f2f2; }
    #error-message { color: red; font-weight: bold; }
  </style>
</head>
<body>

  <h1>边操作边学习 SQL!ORDER BY 实战演练</h1>
  <p>在下方文本框中输入 SQL 语句,然后点击“执行 SQL”按钮,查询将在 <code>products</code> 表上执行。</p>

  <textarea id="sql-input">-- 在此输入SQL语句,试试看不同排序方式!
SELECT * FROM products ORDER BY price DESC;</textarea>
  <button onclick="executeQuery()">执行 SQL</button>

  <h2>查询结果</h2>
  <div id="result-container"></div>
  <div id="error-message"></div>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.3/sql-wasm.js"></script>
  <script>
    let db;

    async function initDb() {
      const SQL = await initSqlJs({
        locateFile: file => `https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.3/${file}`
      });
      db = new SQL.Database();
      
      // 创建表并插入示例数据
      const createTableSQL = `
        CREATE TABLE products (
          id INT,
          name VARCHAR(255),
          category VARCHAR(255),
          price INT,
          release_date DATE
        );
        INSERT INTO products (id, name, category, price, release_date) VALUES
        (1, '毛绒靠垫', '家居', 3200, '2023-04-15'),
        (2, '专注耳罩', '数码产品', 7800, '2023-11-01'),
        (3, '灵感笔记本', '文具', 1200, '2022-08-20'),
        (4, '发光键盘', '数码产品', 15000, '2023-06-30'),
        (5, '超舒适座椅', '家居', 32000, '2022-11-10'),
        (6, '顺滑圆珠笔', '文具', 1200, '2023-09-01'),
        (7, '创作者马克杯', '餐具', 2500, '2023-04-15');
      `;
      db.run(createTableSQL);
      
      // 执行初始查询
      executeQuery();
    }

    function executeQuery() {
      const sqlInput = document.getElementById('sql-input').value;
      const resultContainer = document.getElementById('result-container');
      const errorMessage = document.getElementById('error-message');
      
      resultContainer.innerHTML = '';
      errorMessage.innerHTML = '';

      try {
        const results = db.exec(sqlInput);
        if (results.length > 0) {
          resultContainer.appendChild(createTable(results[0]));
        } else {
          resultContainer.innerHTML = '<p>查询成功,但无返回结果(如 CREATE TABLE、INSERT 等)</p>';
        }
      } catch (e) {
        errorMessage.textContent = '错误:' + e.message;
      }
    }

    function createTable(result) {
      const table = document.createElement('table');
      const thead = document.createElement('thead');
      const tbody = document.createElement('tbody');
      const headerRow = document.createElement('tr');

      result.columns.forEach(colName => {
        const th = document.createElement('th');
        th.textContent = colName;
        headerRow.appendChild(th);
      });
      thead.appendChild(headerRow);

      result.values.forEach(rowData => {
        const tr = document.createElement('tr');
        rowData.forEach(cellData => {
          const td = document.createElement('td');
          td.textContent = cellData;
          tr.appendChild(td);
        });
        tbody.appendChild(tr);
      });

      table.appendChild(thead);
      table.appendChild(tbody);
      return table;
    }

    initDb();
  </script>
</body>
</html>

了解这些能让你脱颖而出!ORDER BY 的注意事项

最后,让我们介绍一些在使用 ORDER BY 时需要注意的事项,以及几个实用的小技巧。

如何处理 NULL 值

当数据中包含 NULL(表示无值)时,ORDER BY 会如何处理呢?这在不同的数据库中行为略有不同,但通常情况下,NULL 会被排在最前(NULLS FIRST)或最后(NULLS LAST)。如果用于排序的字段可能包含 NULL 值,建议先进行测试,以避免出现非预期的排序结果。

关于性能问题

如果你要对数百万条数据使用 ORDER BY 排序,数据库的负载可能会大幅增加,查询速度也会变慢。特别是在没有索引的字段上进行排序时,性能更容易下降。如果你经常对某些字段进行排序,建议考虑使用数据库的 索引 功能,这可能会大幅提升显示速度。虽然这属于中级内容,但提前了解总是好的。

可以根据未在 SELECT 中出现的列进行排序

这可能听起来有些奇怪,但 ORDER BY 可以使用 SELECT 语句中未指定的列进行排序。例如,你只想显示商品名称和价格,但想按照“发布日期最新”来排序:

-- 仅显示 name 和 price,但根据 release_date 排序
SELECT name, price FROM products ORDER BY release_date DESC;

这种将显示内容和排序条件分离的能力,是 SQL 强大的体现之一。


总结:掌握 ORDER BY,迈出数据活用的第一步!

本文详细介绍了 SQL 中的 ORDER BY 子句,从基础用法到多条件排序,再到一些进阶技巧。最后我们来回顾一下重点:

ORDER BY 是将数据库中提取的数据以用户更易理解、更清晰的方式呈现的关键技能。请充分利用本文提供的示例代码和在线练习环境,尝试各种排序方式。掌握这些技巧后,你会发现 Web 开发或数据分析变得更加有趣且高效!