首页 > 数据库 > mysql教程 > SQL JOIN 中的 WHERE 与 ON:何时应该使用每个子句?

SQL JOIN 中的 WHERE 与 ON:何时应该使用每个子句?

DDD
发布: 2025-01-05 13:10:44
原创
270 人浏览过

WHERE vs. ON in SQL JOINs: When Should I Use Each Clause?

探索 JOIN 中 WHERE 子句和 ON 条件的区别

SQL 实践者在执行 JOIN 操作时经常交替使用 WHERE 子句和 ON 条件。虽然两种方法可以返回相同的结果,但需要考虑一些细微差别。

在提供的示例中,提供了两个 SQL 查询:

SELECT *
FROM Foo AS f
INNER JOIN Bar AS b ON b.BarId = f.BarId
WHERE b.IsApproved = 1;
登录后复制

SELECT *
FROM Foo AS f
INNER JOIN Bar AS b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
登录后复制

两个查询返回相同的行集,但它们的执行有一个关键的区别。当过滤器放置在 WHERE 子句中时,它会在 JOIN 操作之后应用。这意味着 JOIN 将从两个表中检索所有匹配的行,即使是 b.IsApproved 为 false 的行。然后,WHERE 子句会过滤掉不满足条件 b.IsApproved = 1 的行。

相反,当过滤器置于 ON 条件中时,会在 JOIN 之前评估条件。因此,只有 b.BarId 和 b.IsApproved 都满足指定条件的行才会包含在 JOIN 中。

外部联接和过滤器放置

但是,在处理外连接时,这种差异变得尤为重要。考虑以下左外连接查询:

SELECT *
FROM Foo AS f
LEFT OUTER JOIN Bar AS b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
登录后复制

在这种情况下,ON 条件下的过滤器将排除 b.IsApproved 为 false 的行或给定 f 没有匹配的 b.BarId 的行.BarId。此行为与将过滤器放在 WHERE 子句中不同:

SELECT *
FROM Foo AS f
LEFT OUTER JOIN Bar AS b ON (b.BarId = f.BarId)
WHERE b.IsApproved = 1;
登录后复制

在第二个查询中,b.IsApproved 为 false 或涉及失败联接的行仍将返回,但 b.IsApproved 将返回设置为 NULL。

因此,在使用外连接时,必须仔细考虑过滤器的放置。 ON 条件过滤连接之前的行,而 WHERE 子句过滤连接之后的结果。

为了完成讨论,如果您希望在左外连接中使用 OPTIONAL 过滤器,以下查询演示了正确的位置:

SELECT *
FROM Foo AS f
LEFT OUTER JOIN Bar AS b ON (b.BarId = f.BarId)
WHERE b.IsApproved IS NULL OR b.IsApproved = 1;
登录后复制

此查询返回连接成功且 b.IsApproved 满足条件的行,以及连接失败的行(导致 NULL 值)对于 b.IsApproved)。

以上是SQL JOIN 中的 WHERE 与 ON:何时应该使用每个子句?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板