这可能是重复但我不知道如何正确搜索。我可以编写基本的sql,并且知道概念'笛卡尔积['但我总是在某种程度上对联接中的 感到困惑。 sqlserver中的示例:
A | B
--+--
1 | 2
2 | 3
select * from ta left join tb on ta.A = 2 --??!
A | B
--+--
1 | Null
2 | 2
2 | 3
select * from ta left join tb on tb.B = 2 --seems easier to understand
A | B
--+--
1 | 2
2 | 2
任何人都可以解释第一个sql( on ta.A = 2 ),为什么A列未被过滤。顺便说一句,我知道最常用的ta.ColA = tb.ColB,但在这个问题中,我只是想知道 on 是如何工作的。
答案 0 :(得分:3)
在LEFT JOIN
中,联接左侧的所有行都将始终保留。 ON
条件确定右侧的任何行是否将成功连接到这些行。
所以,
select * from ta left join tb on ta.A = 2 --??!
A | B
--+--
1 | Null
2 | 2
2 | 3
当A
等于1
时,条件ta.A = 2
永远不会成立,因此保留tb
中的 no 行。< / p>
当A
等于2
时,条件ta.A = 2
为真,因此来自tb
的所有行都会加到这些行中在ta
。
答案 1 :(得分:3)
LEFT JOIN
始终遵循以下规则:
ON ...
子句查找连接右侧的所有匹配行,以查找这些行。NULL
因此,您的ON TA.A=2
仅用于过滤右侧的行。
现在,你的问题中有一个错误,这使得阅读问题变得更加困难。
此输出:
A | B
--+--
1 | Null
1 | 2 <-- notice A=1 here, this is incorrect
2 | 3
应该是这样的:
A | B
--+--
1 | Null
2 | 2 <-- notice A=2 here
2 | 3
基本上,您的查询执行此操作:
TA
TB
的行TA.A=2
为真的行,这只会在您A=2
行时发生,这就是为什么您有Null
的行A=1
。TB
行,因此所有这些行都将与A=2
中的单行合并。