跳到正文
IGCSE·Tuition
计算机科学 · 常见难点

我的 SQL 查询条件组合错了

查询能正常运行,没有报错,可返回的行却不是你想要的那些。

本页内容
  1. 为什么会出现错误的分组?
  2. 例题
  3. 要避免的错误
  4. 每次都能发现问题的流程
  5. 自测
  6. 接下来

当 WHERE 子句同时出现 AND 和 OR 时,查询按自己的分组规则执行,而不是按中文句子听起来的意思。 在标准 SQL 中,AND 先于 OR 计算。用括号可以自己决定分组。

带筛选条件的查询属于数据库与查询推理。写一个简单的 SELECT 筛选和用正确的布尔分组组合条件这两课会一步步建立这项技能。

为什么会出现错误的分组?

我们说“2015 年后出版的科幻或奇幻书”,脑子里自动分成(科幻或奇幻)并且 2015 年后。SQL 不读中文。它看到用 OR 和 AND 连起来的三个条件,就按优先级计算:先 AND,后 OR。

这意味着同样的一句话可能是两个不同的查询。只有括号才能确定含义。

例题

名为 Books 的表有五行。

idtitlegenreyear
1DuneSciFi1965
2NovaFantasy2019
3OrbitSciFi2021
4EmberFantasy2010
5DriftMystery2022

目标: 列出 2015 年后出版的 SciFi 或 Fantasy 书的书名。

尝试 A,没有括号:

SELECT title
FROM Books
WHERE genre = 'SciFi' OR genre = 'Fantasy' AND year > 2015;

第一步。 AND 先结合,所以查询被理解为:genre = ‘SciFi’ OR(genre = ‘Fantasy’ AND year > 2015)。

第二步。 每一行 SciFi 都符合,不管年份:Dune(1965)和 Orbit(2021)。

第三步。 Fantasy 行只有年份在 2015 年后才符合:Nova(2019)符合,Ember(2010)不符合。

A 的结果: Dune、Nova、Orbit。共三行,而 Dune 并不是 2015 年后出版的。

尝试 B,加括号:

SELECT title
FROM Books
WHERE (genre = 'SciFi' OR genre = 'Fantasy') AND year > 2015;

第一步。 先算括号:第 1 到 4 行是 SciFi 或 Fantasy(Drift 是 Mystery,被排除)。

第二步。 再对这些行应用 year > 2015:Nova(2019)和 Orbit(2021)留下,Dune(1965)和 Ember(2010)被淘汰。

B 的结果: Nova、Orbit。两行,正是目标要求的。

要避免的错误

错误一:没加括号。 如尝试 A,查询能运行,却在回答另一个问题。因为查询本身合法,所以没有任何警告。

错误二:中文说“或”的地方写成了 AND。 genre = 'SciFi' AND genre = 'Fantasy' 要求一个字段同时是两种类型。没有一行能做到,所以返回零行。

更正: 先把条件用话说出来,决定分组,再写括号。如果你想表达“其中任意一个”,就在括号里用 OR。

每次都能发现问题的流程

  1. 把问题写成一句话,并给各组划线。
  2. 写查询时,在每一组外面加括号。
  3. 取五行样本,手动标出符合的行。
  4. 运行或跟踪查询,与你的标记对比。

伪代码跟踪训练器和 Python 推理沙盒在小算法上练习的,正是这种手动跟踪的习惯。

自测

使用上面的 Books 表。

1. SELECT title FROM Books WHERE genre = 'Mystery' OR year < 2000; 返回什么?

Show answerDrift(Mystery)和 Dune(1965,早于 2000)。两个条件用 OR 连接,所以一行只需满足其一。结果是 Dune 和 Drift。

2. 写一个查询:2000 年后的 SciFi 书,并且 id 大于 1。

Show answer`SELECT title FROM Books WHERE genre = 'SciFi' AND year > 2000 AND id > 1;` 只有 Orbit 符合。三个条件都用 AND,所以不需要括号,但一行必须全部通过。

3. 查询需要 Fantasy 书,或者 2020 年后的任何书。WHERE genre = 'Fantasy' OR year > 2020 返回哪些行?

Show answerNova 和 Ember(Fantasy),加上 Orbit(2021)和 Drift(2022)。Dune 既不是 Fantasy,也不晚于 2020。结果共四行。

接下来

在解释查询为什么返回零行中练习分组,如果逻辑运算符本身还不牢,先复习计算带括号的逻辑表达式。

如果你会写 SQL,却总是对结果没把握,一对一线上计算机科学补习可以从你自己的查询出发,从 RM80 起的付费试听课开始。

常见问题

为什么我的查询返回了我不想要的行?

通常是 AND 和 OR 混用却没有加括号。在标准 SQL 中,AND 先于 OR 计算,所以条件的分组与你在日常语言里理解的不同。把你想当作一组的条件用括号括起来即可。

为什么 WHERE genre = 'SciFi' AND genre = 'Fantasy' 什么都返回不了?

一行中的一个字段只有一个值,不可能同时等于两个不同的值。若想接受其中任意一个,就在两个条件之间用 OR;后面还有其他条件时,再加括号。

我应该一直加括号吗?

只要 WHERE 子句同时出现 AND 和 OR,就应该加。括号不花任何代价,能让读者看清你的意图,也消除了到底按哪种分组计算的疑问。

运行前怎样检查查询?

写出五到八行样本数据,手动套用每个条件,标出符合的行,再与你期望的结果对比。如果两份清单不同,先检查查询里的分组。

更新于:

下一步

如果你的查询能运行却总是返回错误的行,一对一老师可以听你把查询念出来,指出意思和写法是从哪里开始偏离的。

一小时付费试听课,按所安排老师确认的收费,RM80 起。 其他费用、时间安排及后续课程,在试听课后由家长与老师直接确认。

补习由家长或监护人安排。用 WhatsApp 把这页发给他们,他们就可以替你咨询。

是家长或监护人?在这里咨询

已通过我们的服务帮助 9,000+ 名学生