JOIN中的IS NULL条件与查询中的WHERE之间的差异

时间:2015-09-22 10:18:09

标签: sql-server tsql left-join where

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

2 个答案:

答案 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