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