在 SQL 中组合使用 WHERE、ORDER BY 和 LIMIT
第 2.8 课 · 阅读时间:约 6 分钟 · 练习题 ↓
大多数实际的 SQL 查询都会组合使用 WHERE、ORDER BY 和 LIMIT:先过滤行,再排序,最后只返回需要的部分。在本课中,你将学习这些子句必须遵循的书写顺序、数据库实际处理它们的顺序,以及如何编写带过滤的前 N 行查询和分页查询。
在本模块中,你学会了用 WHERE 过滤行、用 ORDER BY 排序、用 LIMIT 限制结果。单独使用时,每个子句只解决一个小问题。组合起来,它们可以回答典型的业务问题:“重置成本最低的 5 部电影”、“最近超过 10 美元的付款”、“搜索结果的第 2 页”。
子句的书写顺序
SELECT 查询的子句必须按固定顺序书写。顺序不对时,数据库会返回语法错误。
SELECT columns
FROM table_name
WHERE condition
ORDER BY sort_columns
LIMIT row_count OFFSET skip_count;
SELECT:返回哪些列。FROM:读取哪张表。WHERE:保留哪些行。ORDER BY:如何排序。LIMIT/OFFSET:返回排序结果中的哪一部分。
这是你目前已学过的子句的顺序;在第 4 模块中,GROUP BY 和 HAVING 会位于 WHERE 和 ORDER BY 之间。
逻辑处理顺序
数据库并不是按照查询的书写顺序来处理它的。从逻辑上讲,步骤如下:
| 步骤 | 子句 | 发生了什么 |
|---|---|---|
| 1 | FROM | 选择源表 |
| 2 | WHERE | 删除不满足条件的行 |
| 3 | SELECT | 计算结果中的列和表达式 |
| 4 | ORDER BY | 对行排序 |
| 5 | LIMIT / OFFSET | 返回排序后的行中需要的部分 |
这个顺序解释了两条重要规则:
WHERE不能使用SELECT中的列别名:在第 2 步时它们还不存在。LIMIT是在过滤和排序之后应用的,所以“前 5 名”指的是过滤后排在前面的 5 行,而不是随机取 5 行再过滤。
优化器内部可能以不同的方式执行查询,但结果总是与按这个顺序执行各步骤的结果相同。
带过滤的前 N 行查询
最短的五部低价电影
SELECT title, length, replacement_cost
FROM film
WHERE replacement_cost < 15.00
ORDER BY length, title
LIMIT 5;
结果:重置成本低于 15 美元的电影中最短的 5 部。
最近的大额付款
SELECT payment_id, customer_id, amount, payment_date
FROM payment
WHERE amount >= 10.00
ORDER BY payment_date DESC
LIMIT 10;
结果:最近 10 笔金额不低于 10 美元的付款。
按字母查找演员
SELECT first_name, last_name
FROM actor
WHERE last_name LIKE 'B%'
ORDER BY first_name, last_name
LIMIT 3;
结果:姓氏以“B”开头的演员中,按名字排序的前 3 位。
对过滤后的列表分页
应用程序通常对过滤并排序后的列表分页,例如搜索结果。三个子句缺一不可:
WHERE选出用户要查找的行。ORDER BY固定顺序,使各页之间的行不会重复或丢失。LIMIT和OFFSET选择页面:LIMIT S OFFSET (N - 1) * S。
SELECT first_name, last_name
FROM actor
WHERE first_name LIKE 'A%'
ORDER BY last_name, first_name
LIMIT 5 OFFSET 5;
结果:名字以“A”开头、按姓氏排序的演员列表的第 2 页(第 6 到第 10 行)。
要点:
- 书写顺序是
SELECT→FROM→WHERE→ORDER BY→LIMIT。 - 逻辑顺序是
FROM→WHERE→SELECT→ORDER BY→LIMIT。 WHERE在SELECT之前应用,所以不能使用列别名;ORDER BY可以。LIMIT从已经过滤并排序的结果中取行。- 要让前 N 行列表和分页保持稳定,请使排序唯一。
常见问题
SQL 中 WHERE、ORDER BY 和 LIMIT 的正确顺序是什么?
先 WHERE,再 ORDER BY,最后 LIMIT:SELECT ... FROM ... WHERE ... ORDER BY ... LIMIT ...。其他任何顺序都会导致语法错误。
SQL 按什么顺序执行查询?
从逻辑上讲:FROM、WHERE、GROUP BY、HAVING、SELECT、ORDER BY、LIMIT。这就是为什么 WHERE 不能使用 SELECT 中的别名,而 ORDER BY 可以。
LIMIT 是在 WHERE 之前还是之后应用?
之后。数据库先用 WHERE 过滤行,再用 ORDER BY 排序,最后才返回 LIMIT 指定数量的行。