排序、LIMIT 和 DISTINCT
到现在为止,结果里行的顺序都是数据库自己定的。看起来像是按 id 排,可没人保证:换一个数据库、数据多了,顺序都可能变。想要确定的顺序,就加一个 ORDER BY:
1SELECT name, price2FROM products3ORDER BY price;
| name | price |
|---|---|
| 笔记本 | 4.50 |
| 中性笔(10 支) | 6.00 |
| 数据线 | 8.50 |
| 咖啡杯 | 9.90 |
| 帆布袋 | 11.00 |
| 水杯 | 12.00 |
| 手机壳 | 15.00 |
| 台灯 | 25.00 |
| 双肩包 | 39.90 |
| 耳机 | 59.00 |
ORDER BY
ORDER BY 列 按这一列从小到大排,写在 WHERE 后面。数字比大小,日期比早晚。按注册日期排的客户,最早的在前:
1SELECT name, joined2FROM customers3ORDER BY joined;
| name | joined |
|---|---|
| 林晓 | 2025-01-12 |
| 王磊 | 2025-02-03 |
| 陈静 | 2025-02-20 |
| 张伟 | 2025-03-15 |
| 刘洋 | 2025-04-01 |
| 赵敏 | 2025-05-18 |
| 孙强 | 2025-06-09 |
| 周婷 | 2025-07-21 |
| 吴昊 | 2025-08-30 |
| 郑雪 | 2025-09-14 |
从小到大叫升序,写 ASC;不写就是升序,所以 ORDER BY joined ASC 和上面一样。
从大到小:DESC
在列名后面加 DESC,就是降序,从大到小。最新的订单排在前面:
1SELECT id, order_date, status2FROM orders3WHERE status = '已发货'4ORDER BY order_date DESC;
| id | order_date | status |
|---|---|---|
| 11 | 2025-10-22 | 已发货 |
| 10 | 2025-10-20 | 已发货 |
| 8 | 2025-10-12 | 已发货 |
| 6 | 2025-10-03 | 已发货 |
| 5 | 2025-10-01 | 已发货 |
| 3 | 2025-09-18 | 已发货 |
| 2 | 2025-09-05 | 已发货 |
| 1 | 2025-09-02 | 已发货 |
这条查询先用 WHERE 挑出已发货的订单,再把它们排序。排序用的列也不一定要选出来:ORDER BY stock 照样可以只显示 name。
文字怎么排
文字也能排序。英文按字母顺序;汉字按编码排,不是按拼音,也不是按笔画:
1SELECT name2FROM products3ORDER BY name;
| name |
|---|
| 中性笔(10 支) |
| 双肩包 |
| 台灯 |
| 咖啡杯 |
| 帆布袋 |
| 手机壳 |
| 数据线 |
| 水杯 |
| 笔记本 |
| 耳机 |
「中」的编码最小,所以中性笔排第一;「耳」的编码最大,耳机排最后。想按拼音排,要另外设置,这门课不讲。
按几列排
ORDER BY 后面可以写好几列,用逗号隔开:先按第一列排,第一列一样的,再按第二列排。每一列可以有自己的 ASC 或 DESC:
1SELECT name, category, price2FROM products3ORDER BY category, price DESC;
| name | category | price |
|---|---|---|
| 水杯 | 厨房 | 12.00 |
| 咖啡杯 | 厨房 | 9.90 |
| 耳机 | 数码 | 59.00 |
| 台灯 | 数码 | 25.00 |
| 手机壳 | 数码 | 15.00 |
| 数据线 | 数码 | 8.50 |
| 中性笔(10 支) | 文具 | 6.00 |
| 笔记本 | 文具 | 4.50 |
| 双肩包 | 箱包 | 39.90 |
| 帆布袋 | 箱包 | 11.00 |
同一个分类的商品排在一起,分类里面贵的在前。点单步,看 ORDER BY 把行重新排了一遍。
小技巧: 第一列有一样的值时,最好再加一列(比如 id)把顺序定死,不然这几行谁前谁后还是说不准。
前几名:LIMIT
LIMIT 3 只要结果的前 3 行,写在最后。和 ORDER BY 一起用,就是「前 3 名」。最贵的 3 件商品:
1SELECT name, price2FROM products3ORDER BY price DESC4LIMIT 3;
| name | price |
|---|---|
| 耳机 | 59.00 |
| 双肩包 | 39.90 |
| 台灯 | 25.00 |
点单步:先按价格从高到低排好,最后 LIMIT 只留下前 3 行。不写 ORDER BY 的 LIMIT 3 只是「随便 3 行」,没有意义。
LIMIT 是 MySQL 的写法(SQLite、PostgreSQL 也认)。别的数据库可能写成 FETCH FIRST 3 ROWS ONLY(标准写法),SQL Server 写成 SELECT TOP 3 …。
结果是哪件商品?
1SELECT name, stock2FROM products3ORDER BY stock4LIMIT 1;
ORDER BY stock 不写方向,就是从小到大,库存最少的排第一。LIMIT 1 只留第一行:库存 0 的台灯。
去掉重复:DISTINCT
客户来自哪些城市?直接查 city,同一个城市会出现好几次:
1SELECT city2FROM customers;
| city |
|---|
| 上海 |
| 北京 |
| 上海 |
| 广州 |
| 成都 |
| 北京 |
| 广州 |
| 上海 |
| 成都 |
| 杭州 |
SELECT DISTINCT 把一模一样的行只留一行:
1SELECT DISTINCT city2FROM customers3ORDER BY city;
| city |
|---|
| 上海 |
| 北京 |
| 广州 |
| 成都 |
| 杭州 |
「上」的编码比「北」小,所以上海排在北京前面。DISTINCT 后面写几列,就按这几列一起去重:两行要每一列都一样,才算重复。
练一练
写好查询,点检查。提示随便看,实在想不出来再看答案。
库存最多的 3 件
✓查出库存最多的 3 件商品,显示 name 和 stock 两列,库存多的在前。
| name | stock |
|---|---|
| 数据线 | 200 |
| 笔记本 | 120 |
| 中性笔(10 支) | 80 |
1SELECT name, stock2FROM products;
最新的待发货订单
✓查出待发货的订单,显示 id 和 order_date 两列,最新的在前。
| id | order_date |
|---|---|
| 12 | 2025-10-25 |
| 9 | 2025-10-15 |
| 7 | 2025-10-10 |
1SELECT id, order_date2FROM orders3ORDER BY order_date;
下过单的客户
✓订单表里出现过哪些客户编号?显示 customer_id 一列,每个编号只出现一次,从小到大。
| customer_id |
|---|
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 7 |
| 8 |
1SELECT customer_id2FROM orders;
这一课学会了
- 不写
ORDER BY,行的顺序没人保证;要确定的顺序就写ORDER BY。 ASC从小到大(不写就是它),DESC从大到小;汉字按编码排,不按拼音。ORDER BY a, b先按a排,a一样的再按b排;每列有自己的方向。LIMIT n只要前 n 行,和ORDER BY一起用就是「前 n 名」;别的数据库可能写FETCH FIRST n ROWS ONLY或TOP n。SELECT DISTINCT去掉一模一样的行。