JOIN 中的 IS NULL 条件与查询中的 WHERE 之间的区别

Difference between IS NULL criteria in JOIN and WHERE in a query

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

在查询 1 中,我们在连接条件中有 b.id is null,这是因为 LEFT JOIN 在 A returns 上,A 的所有行都与 JOIN 条件无关,因此 returns table A 3 行。

在查询 2 中,首先 LEFT JOIN 在 A returns 3 行上,然后 where b.id is null 应用于这 3 行,留下第三行,结果仅 1 行 用于 id=3 的第三行。

进一步说明:

您的评论

Though in Query1 how come b.id is null ??

需要详细说明

正如我在查询 1 中所说,对于 A 的每一行,Left join 中返回一行,而不考虑 JOIN

的条件

所以您的加入条件实际上是

a.id = b.id 并且 b.id 为空

两个条件之间的逻辑 And 不能同时为真,就好像 b.id 为空 为真那么 a.id=null 被匹配,基本上是 null

在此 fiddle 中给出了输出: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

这个不正确:

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 table 的所有行,但#t2.

的所有空值

这个是正确的:

select *
from
  #t1 a left join #t2 b
  on a.id = b.id
where
  b.id is null

您正在使用 LEFT JOIN,因此您的查询将 return 来自 #t1 的所有行,并且仅来自 #t2 的连接成功的行(并且它会在 a.id = b.id 时成功)。

当加入不成功时,b.id将被设置为空。使用 WHERE b.id is null 您将仅获得连接不会成功的行,并且您将获得 #t1 中不存在于 #t2 中的所有值。

您可以尝试 运行 此查询以查看实际发生的情况并更好地理解逻辑:

select *
from
  #t1 a left join #t2 b
  on a.id = b.id