在我看来,这两个查询都会返回相同的结果:
SELECT * FROM table1
LEFT JOIN table2 ON table1.key = table2.key AND table2.foo = 1
SELECT * FROM table1
LEFT JOIN table2 ON table1.key = table2.key
WHERE table2.foo = 1
这是对的吗?如果是这样,它们之间是否存在任何有意义的差异?
答案 0 :(得分:3)
他们不会返回相同的结果。
第一个查询将包含table1中的记录,即使foo为1也没有匹配的table2记录。
第二个查询将不包含来自table1的记录,其中没有匹配的table2记录,其foo值为1.
这种模式(LEFT JOIN t ON id=id and other='literal'
)很常见。例如,在我目前使用的系统中,我们有一个address_master
表,其中person_id
列为匹配地址的人员,addr_cde
(地址代码)列告诉您什么样的地址(家庭,工作,度假等)。所以看到像这样的联接是很常见的:
LEFT JOIN address_master a ON a.person_id = Person.Id AND a.addr_cde = 'Work'
如果我们将addr_cde = 'Work'
表达式移到WHERE
子句,那么即使我们想要查看该人的其他数据。
答案 1 :(得分:2)
这不正确
如果我们假设下面的样本数据,则结果不一样:
T1
KEY
---
1
2
T2
KEY Foo
--- ---
1 1
2 4
SELECT * FROM table1
LEFT JOIN table2 ON table1.key = table2.key AND table2.foo = 1
T1.KEY T2.KEY T2.Foo
------ ------ ------
1 1 1
2 NULL Null
SELECT * FROM table1
LEFT JOIN table2 ON table1.key = table2.key
WHERE table2.foo = 1
T1.KEY T2.KEY T2.Foo
------ ------ ------
1 1 1
答案 2 :(得分:1)
The following shows how the 2 queries are different:
declare @t1 table(id int);
insert into @t1 values (1), (2);
declare @t2 table(id int, col int);
insert into @t2 values(1,1), (3,1);
第一个示例 - 右表上具有Where过滤器的LEFT连接:
select *
from @t1 t1
left join @t2 t2
on t1.id = t2.id
where t2.col = 1;
正确的LEFT连接,用于过滤ON子句中的右表:
select *
from @t1 t1
left join @t2 t2
on t1.id = t2.id
AND t2.col = 1;
INNER JOIN。这给出了与第一个例子相同的结果 - LEFT JOIN和Where子句中右表的过滤器:
select *
from @t1 t1
join @t2 t2
on t1.id = t2.id
where t2.col = 1;