人人都能学编程
English 开始学习
核心 · 数据库第 2 课 / 共 6 课免费阅读

排序与截取 · SQL 与数据库

怎么给结果排序、截取、去重?

课程目录

为什么需要它

一页搜索结果就是排好序、截取过的列表:最便宜的十个航班,最新的帖子排在最前。没有 ORDER BY 时,数据库可以按任何顺序返回行,而且每次都可能不一样。

直觉理解

把查询想成一条流水线,顺序是:

  1. FROM 选表
  2. WHERE 扔掉不要的行
  3. SELECT 选列,也可以算出新列
  4. ORDER BY 给剩下的排序
  5. LIMIT 只留前几行

AS 给算出来的列起名字,DISTINCT 去掉重复的行。

定义

ORDER BY 排序

Sorts rows by one or more columns, ascending (`ASC`, the default) or descending (`DESC`). Ties are broken by the next column listed.
按一列或多列排序,升序(`ASC`,默认)或降序(`DESC`)。前一列相同时,按后面列出的列继续排。

LIMIT

Returns at most this many rows. `LIMIT 3 OFFSET 3` skips three rows first, which is how page 2 of a list works.
最多返回这么多行。`LIMIT 3 OFFSET 3` 先跳过三行,列表的第 2 页就是这么做的。

示例

从贵到便宜排序,再留三行。

SELECT name, price
FROM products
ORDER BY price DESC
LIMIT 3;
输出
name | price
Backpack | 25.0
Lamp | 18.0
Mug | 6.0
逐步执行
  1. L3DESC:大的在前。Backpack 25.0、Lamp 18.0、Mug 6.0……
  2. L4三行之后就停。Backpack, Lamp, Mug

计算列与 DISTINCT

在互动课里运行

price * 1.2 对每一行都算一次,用 AS 起名字。DISTINCT 把五个类别变成三个。

SELECT name, price * 2 AS two_of_them
FROM products
WHERE category = 'home';

SELECT DISTINCT category FROM products ORDER BY category;
输出
name | two_of_them
Lamp | 36.0
Mug | 12.0

category
bags
home
paper
逐步执行
  1. L1这个新列只存在于结果里,表本身没变。Lamp 36.0, Mug 12.0
  2. L5bags、home、paper:各一次,按字母排序。

常见错误

依赖默认顺序

行的返回顺序是数据库觉得最快的顺序。只要顺序重要,就每次都写 ORDER BY。

以为 LIMIT 先执行

LIMIT 永远最后执行。ORDER BY price LIMIT 1 是所有商品里最便宜的那个,而不是随便拿一行再排序。

小测验

1. 这段代码会输出什么?

SELECT name FROM customers ORDER BY name DESC LIMIT 2;
  1. A
    name
    Eli
    Dana
  2. B
    name
    Ada
    Bo
  3. C
    name
    Dana
    Eli
查看答案

答案:A

DESC 从 Z 到 A 排:Eli、Dana、Chen、Bo、Ada。LIMIT 留前两个。

2. 这段代码会输出什么?

SELECT DISTINCT day FROM orders WHERE qty < 3 ORDER BY day;
  1. A
    day
    2025-03-02
    2025-03-03
    2025-03-05
  2. B
    day
    2025-03-02
    2025-03-03
    2025-03-05
    2025-03-05
  3. C
    day
    2025-03-05
查看答案

答案:A

订单 3、4、5、6 的数量小于 3。其中两个都在 2025-03-05,DISTINCT 只留一个。

动手练习

3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。

  1. 预测输出按两列排序

    准确写出查询结果。

  2. 改需求最新的在前

    修改查询,返回最近的 3 笔订单,最新的在前。列保持不变。

  3. 从零写含税价

    返回每件商品的 name,以及加 10% 税后的价格,列名叫 with_tax(price × 1.1),便宜的在前。

在互动课里练这一课

打开互动课,这些例子都能直接改、直接运行,练习题提交马上判题。免费开始,不用注册。

互动课按顺序解锁:前面的课还没学,会先带你到课程地图。

本课术语

术语中文英文定义
Ascending (ASC)升序From small to large, A to Z, old to new.
Descending (DESC)降序From large to small, Z to A, new to old.
Alias (AS)别名A new name for a column or table, valid inside one query.