课程 2.7:综合运用:WHERE、ORDER BY 和 LIMIT
到目前为止,我们已经学习了如何过滤行(WHERE)、对其排序(ORDER BY)以及限制结果数量(LIMIT)。在实际场景中,您几乎总是会将这些子句一起使用,以获取所需的确切数据。
子句的顺序
SQL 对这些子句在 查询文本中的出现顺序 有严格要求。如果您将它们放在错误的顺序,数据库将返回错误。
以下是 仅针对我们在本模块中学习的子句 的正确顺序。SQL 查询部分的完整顺序更广泛,并将在您学习新的语言结构时扩展。
查询文本中的正确顺序是:
SELECT(选择哪些列?)FROM(来自哪个表?)WHERE(首先过滤行)ORDER BY(对过滤后的行进行排序)LIMIT(从排序后的列表中取前 X 个结果)OFFSET(如有需要,跳过 X 行)
重要提示:这个顺序描述的是 您编写查询的方式,而不是其逻辑处理顺序。在逻辑上,SQL 处理查询的各个部分是不同的。
逻辑处理顺序
当您运行一个组合查询时,数据库的处理方式概念上如下:
- 首先,它从
FROM确定数据源。 - 接下来,它应用
WHERE中的过滤条件。 - 然后,它从
SELECT形成所选列列表。 - 然后根据
ORDER BY对结果进行排序。 - 最后,它应用
OFFSET跳过行(如有需要),然后使用LIMIT返回所需的排序行子集。
这就是为什么 WHERE 不能引用在 SELECT 中定义的别名:在过滤阶段,所选列列表尚未在逻辑上形成。
示例
示例 1:查找 5 部最短的动作电影
在此示例中,我们首先按类别过滤(概念上),然后按长度排序,最后限制结果。
SELECT title, length, replacement_cost
FROM film
WHERE replacement_cost < 20.00
ORDER BY length ASC
LIMIT 5;
示例 2:最新的高价值租赁
此查询查找持续超过 5 天的 10 个最新租赁。
SELECT rental_id, rental_date, return_date
FROM rental
WHERE return_date - rental_date > 5
ORDER BY rental_date DESC
LIMIT 10;
示例 3:查找特定演员
查找姓氏以 'B' 开头的前 3 位演员,按名字字母顺序排序。
SELECT first_name, last_name
FROM actor
WHERE last_name LIKE 'B%'
ORDER BY first_name
LIMIT 3;
使用 WHERE 和 ORDER BY 的分页
在上一课中,我们看到了使用 LIMIT 和 OFFSET 的基本分页。在实际应用中,您通常会在 过滤 和 排序 的列表中进行分页。
为什么我们需要 WHERE 和 ORDER BY 进行分页?
- 过滤: 用户通常希望查看特定的数据子集(例如,“活动”产品或“喜剧”电影)。
- 一致性: 如果没有
ORDER BY,数据库可能会在您转到下一页时以不同的顺序返回行,导致某些项目出现两次而其他项目被遗漏。
分页公式
要实现“第 N 页”的分页,每页有“S”个结果:
LIMIT SOFFSET (N - 1) * S
组合示例:以 'A' 开头的演员的第 2 页
如果我们想显示姓氏以 'A' 开头的演员的第二页(每页 5 个结果),按姓氏排序:
SELECT first_name, last_name
FROM actor
WHERE first_name LIKE 'A%'
ORDER BY last_name
LIMIT 5 OFFSET 5; -- 第 2 页:跳过 5,取 5
本课的关键要点:
- 遵循严格的语法顺序:
WHERE->ORDER BY->LIMIT。 WHERE子句条件在排序和限制发生 之前 应用。- 这种组合是大多数数据报告和用户界面“前 X”列表的基础。
- 如果您希望结果保持一致,请始终在使用
ORDER BY时使用LIMIT。
在下一个模块中,我们将超越简单的行检索,探索 聚合函数,它允许我们计算整个数据集的总数、平均值和计数。