三表LEFT JOIN搭配WHERE条件未达预期结果问题排查
问题分析与解决方案
你的SQL语句核心问题出在WHERE子句中的c.Indicator = 'Y'条件,它直接把LEFT JOIN的效果变成了INNER JOIN,导致不符合条件的记录被过滤掉,和你的预期不符。
为什么会出现这个问题?
当使用LEFT JOIN时,即使右侧表(这里是Names)没有匹配的记录,左侧表(Versions)的记录依然会被保留,此时右侧表的字段会显示为NULL。但你在WHERE里加了c.Indicator = 'Y',而NULL和任何值比较的结果都是FALSE,所以Versions中ID=3(Version为1.2)的那条记录就被过滤掉了,这和你想要保留这条记录并显示NULL的需求矛盾。
另外,我注意到你写的表名是Version a,但你的原始表实际叫Versions,这是一个小笔误,需要修正。
正确的SQL语句
把c.Indicator = 'Y'移动到LEFT JOIN Names的ON条件中,这样只会关联Names表中符合Indicator='Y'的记录,同时保留Versions中所有以'1'开头的记录:
SELECT a.ID, b.Number, a.Version, c.Name, c.Indicator FROM Versions a LEFT JOIN Cell b ON a.ID = b.ID LEFT JOIN Names c ON a.ID = c.ID AND c.Indicator = 'Y' -- 将筛选条件移至关联阶段 WHERE a.Version LIKE '1%'
验证结果
这条SQL会返回你预期的输出:
| ID | Number | Version | Name | Indicator |
|---|---|---|---|---|
| 1 | 1234 | 1.0 | Joe | Y |
| 2 | 5678 | 1.1 | George | Y |
| 3 | 4786 | 1.2 | NULL | NULL |
简单来说,ON条件是在关联表的时候就筛选匹配的记录,而WHERE是在关联完成后对整个结果集进行筛选,两者的执行时机不同。对于LEFT JOIN来说,把右侧表的筛选条件放在ON里,才能保证左侧表的所有符合条件的记录都被保留。
内容的提问来源于stack exchange,提问作者aditya tandel
相关产品推荐
相关产品推荐

