create table #t1 (id int)
create table #t2 (id int)
insert into #t1 values (1)
insert into #t1 values (2)
insert into #t1 values (3)
insert into #t2 values (1)
insert into #t2 values (2)
我运行了以下查询,我得到了2个不同的输出。
其次是所需的输出。
我无法理解query1给出的输出的原因。
请帮助我理解结果。
-- Query1
select * from #t1 a left join #t2 b on a.id = b.id and b.id is null
-- Query2
select * from #t1 a left join #t2 b on a.id = b.id where b.id is null
答案 0 :(得分:4)
在查询1中,我们在连接条件中有b.id is null
,因为A上的LEFT JOIN
返回A的所有行而不管JOIN条件,因此为表A返回3行。
在查询2中,A上的第一个LEFT JOIN
返回3行,然后在这3行中应用where b.id is null
,这些行离开第三行并导致仅1行 id = 3的第三行。
进一步说明:
您的评论
虽然在Query1中,b.id是怎么回事?
需要详细解释
正如我在查询1中针对A的每一行所述,在左连接中返回了一行而不管JOIN的条件
所以您的加入条件实际上是
a.id = b.id且b.id为空
两个标准之间的逻辑和不能同时为真,如果 b.id为空为真,则a.id = null匹配,基本上为null输出在这个小提琴中给出:http://sqlfiddle.com/#!3/c20ba/1
就像
id | id
________
1 | null
2 | null
3 | null
需要注意的另一点:请注意,在SQL id=NULL
中评估为NULL
。另请注意,在sql查询中执行AND OR等逻辑操作时,NULL表现得非常特殊。请参阅有关此行为的msdn documentation
null and true = null
null and false=false
null and null =null
null or null =null
null or true= true
null or false=null
答案 1 :(得分:2)
这个不正确:
select *
from
#t1 a left join #t2 b
on a.id = b.id and b.id is null
您希望b.id
为空,并且同时为b.id = a.id
。这可能永远不会成立,因此连接不会成功。您将获得#t1表中的所有行,但#t2的所有空值。
这是正确的:
select *
from
#t1 a left join #t2 b
on a.id = b.id
where
b.id is null
您正在使用LEFT JOIN,因此您的查询将返回#t1中的所有行,并且仅返回连接成功的#t2中的行(并且在a.id = b.id
时将成功。)
当联接未成功时,b.id
将设置为null。使用WHERE b.id is null
,您将只获得连接不会成功的行,您将获得#t1中#t2中不存在的所有值。
您可以尝试运行此查询以查看实际发生的情况并更好地理解逻辑:
select *
from
#t1 a left join #t2 b
on a.id = b.id