首页 >数据库 >mysql教程 >为什么在 WHERE 子句中过滤右侧列时,LEFT JOIN 会变成 INNER JOIN?

为什么在 WHERE 子句中过滤右侧列时,LEFT JOIN 会变成 INNER JOIN?

DDD
DDD原创
2024-12-29 14:47:11734浏览

Why Does a LEFT JOIN Become an INNER JOIN When Filtering on a Right-Side Column in the WHERE Clause?

左连接行为问题:使用 WHERE 子句转换为内连接

考虑以下 SQL 语句:

SELECT
    a.foo
    b.bar
    c.foobar
FROM tableOne AS a
INNER JOIN tableTwo AS b ON a.pk = b.fk
LEFT JOIN tableThree AS c ON b.pk = c.fk
WHERE a.foo = 'something'
AND c.foobar = 'somethingelse'

在这种情况下,期望的是左连接行为。然而,观察到的行为是,左连接似乎根据 AND c.foobar = 'somethingelse' 子句的存在而转换为内连接。 tableThree 中缺少相应 'somethingelse' 值的行不会被返回。

理解行为

关键点在于 WHERE 子句和 LEFT JOIN 之间的交互。当在 WHERE 子句中从左联接的右侧指定非 NULL 值时,NULL 值将被消除,从而有效地将联接转变为内联接。

在这种情况下,AND c. foob​​ar = 'somethingelse' 子句过滤掉 tableThree 中 foobar 为 NULL 的行。这意味着仅返回 tableTwo 和 tableThree 中具有匹配非 NULL 值的行。

解决方案

要解决此行为并恢复预期的左连接,有有两个选项:

  1. 修改 WHERE子句:
AND (c.foobar = 'somethingelse' OR c.foobar IS NULL)

此添加允许包含 tableThree 中的 NULL 值,保留左连接行为。

  1. 移动到 Join 谓词:
LEFT JOIN tableThree AS c ON b.pk = c.fk
AND c.foobar = 'somethingelse'

通过移动c.foobar条件放入连接谓词中,查询显式指定连接内所需的过滤条件,确保仅连接匹配的行。

以上是为什么在 WHERE 子句中过滤右侧列时,LEFT JOIN 会变成 INNER JOIN?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn