Sql 从中选择X不在Y中的意外结果

Sql 从中选择X不在Y中的意外结果,sql,sql-server,azure-sql-database,sql-server-2016,Sql,Sql Server,Azure Sql Database,Sql Server 2016,所以 返回6673 select COUNT(*) cnt from docDocument d inner join tblAttachment a on d.AttachmentID = a.ID where a.ContainerID = 1 返回10372 select COUNT(*) from tblAttachment where ContainerID = 1 返回3699,其意义为10372-6673=3699 select COUNT(*) cnt from d

所以

返回6673

select COUNT(*) cnt from docDocument d 
inner join tblAttachment a on d.AttachmentID = a.ID
where
a.ContainerID = 1 
返回10372

select COUNT(*) from tblAttachment 
where 
ContainerID = 1 
返回3699,其意义为10372-6673=3699

select COUNT(*) cnt from docDocument d 
right join tblAttachment a on d.AttachmentID = a.ID
where
a.ContainerID = 1 
AND
d.ID IS NULL
不出所料,返回3699。。。然而

SELECT COUNT(*) FROM
(
select ID from tblAttachment a
where 
a.ContainerID = 1
Except
(
    SELECT AttachmentId from docDocument 
)
) tst
我本以为它会返回3699,但令人惊讶的是它返回了0


有人能解释这些结果吗?

如果子查询返回空值,则NOT IN不再为真,并且不返回任何行

要返回的aviod null值之一:

select COUNT(*) from tblAttachment a
where 
a.ContainerID = 1 AND
a.ID NOT IN
(
    SELECT d.AttachmentId from docDocument  d
)
或切换到空安全设置不存在:

docDocument表中必须有空值…这就是为什么您什么也得不到的原因

请尝试使用不存在的方法

您可以使用EXCEPT运算符

解决方案

从选项卡1中选择名称 除了 从tab2中选择*

输出

select * into #tab1 from (
select 'a' Name union all
select 'b'union all
select 'c'union all
select 'd'union all
select 'e'

)AS A

select * into #tab2 from 
(
select 'd' Name union all
select 'e' union all
select NULL
)AS A

您的not in查询返回空值。所以它显示零记录

这是您现在得到的以下场景。让我们试着理解这一点,并做出改变

Name
----
a
b
c

(3 rows affected)
不存在

左连接

不在


注意:每当Not in查询返回NULL时,外部查询将返回空白数据。

感谢其中的d.AttachmentId不为NULL。我应该想到,在你不孤单之前,空值已经咬了我很多次了。我学会了始终不存在。这也返回0,原因与上面的回答相同,请再次检查。我加入的ID列将不为空。您正在加入可以为NULL的列,因此将一无所获。否则,您可以使用除。从表1中选择名称,但从表2中选择*除外
select COUNT(*) from tblAttachment a
where 
a.ContainerID = 1 AND
NOT EXISTS
(
    SELECT d.AttachmentId from docDocument  d
    WHERE a.ID = d.ID
)
select * into #tab1 from (
select 'a' Name union all
select 'b'union all
select 'c'union all
select 'd'union all
select 'e'

)AS A

select * into #tab2 from 
(
select 'd' Name union all
select 'e' union all
select NULL
)AS A
Name
----
a
b
c

(3 rows affected)
select * 
into #tab1 
from (select 'a' Name union all
      select 'b'union all
      select 'c'union all
      select 'd'union all
      select 'e') AS A

select * 
into #tab2 
from (select 'd' Name union all
      select 'e' union all
      select NULL) AS A
select Name 
from #tab1  
where not exists (select * 
                  from #tab2 
                  where #tab1.Name = #tab2.Name )
select t1.Name 
from #tab1 t1
left join #tab2 t2 on t1.Name = t2.Name 
where t2.Name is null
select * 
from #tab1 
where Name not in (select Name from #tab2)