🙏 感谢您的支持! 我们在七月份已经筹集了 $65 — 这足够我们工作到下个月。请帮助我们保持进度,进一步支持这个项目。 支持这个项目 →
SQL 代码已复制到剪贴板

课程 2.7:综合运用:WHERE、ORDER BY 和 LIMIT

到目前为止,我们已经学习了如何过滤行(WHERE)、对其排序(ORDER BY)以及限制结果数量(LIMIT)。在实际场景中,您几乎总是会将这些子句一起使用,以获取所需的确切数据。

子句的顺序

SQL 对这些子句在 查询文本中的出现顺序 有严格要求。如果您将它们放在错误的顺序,数据库将返回错误。

以下是 仅针对我们在本模块中学习的子句 的正确顺序。SQL 查询部分的完整顺序更广泛,并将在您学习新的语言结构时扩展。

查询文本中的正确顺序是:

  1. SELECT(选择哪些列?)
  2. FROM(来自哪个表?)
  3. WHERE(首先过滤行)
  4. ORDER BY(对过滤后的行进行排序)
  5. LIMIT(从排序后的列表中取前 X 个结果)
  6. OFFSET(如有需要,跳过 X 行)

重要提示:这个顺序描述的是 您编写查询的方式,而不是其逻辑处理顺序。在逻辑上,SQL 处理查询的各个部分是不同的。

逻辑处理顺序

当您运行一个组合查询时,数据库的处理方式概念上如下:

  1. 首先,它从 FROM 确定数据源。
  2. 接下来,它应用 WHERE 中的过滤条件。
  3. 然后,它从 SELECT 形成所选列列表。
  4. 然后根据 ORDER BY 对结果进行排序。
  5. 最后,它应用 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 的分页

在上一课中,我们看到了使用 LIMITOFFSET 的基本分页。在实际应用中,您通常会在 过滤排序 的列表中进行分页。

为什么我们需要 WHERE 和 ORDER BY 进行分页?

  1. 过滤: 用户通常希望查看特定的数据子集(例如,“活动”产品或“喜剧”电影)。
  2. 一致性: 如果没有 ORDER BY,数据库可能会在您转到下一页时以不同的顺序返回行,导致某些项目出现两次而其他项目被遗漏。

分页公式

要实现“第 N 页”的分页,每页有“S”个结果:

  • LIMIT S
  • OFFSET (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

在下一个模块中,我们将超越简单的行检索,探索 聚合函数,它允许我们计算整个数据集的总数、平均值和计数。

尝试解决以下任务,以巩固您在本课中学到的内容。

  1. 检索超过 3 小时的电影
  2. 远程飞机