为什么这个 "not in" 子句不符合我的预期?

Why doesn't this "not in" clause do what I expect?

我正在编写我认为应该使用 "not in" 运算符的简单查询,但它没有按照我的预期进行。

背景:


我有一个工作查询可以执行此操作:

select
    count(ContactID)
from
    Contact left join Company on Contact.CompanyID = Company.CompanyID
where
    Company.CompanyID is null;

这个查询 return 的值 2725538,我认为这是正确的答案(我做了一些简单的 "show me the top 10 rows" 调试,并且它似乎在计算正确的行数)。


我写了第二个查询,我希望得到 return 相同的结果:

select
    count(ContactID)
from
    Contact
where
    CompanyID not in
        (select
            CompanyID
        from
            Company)

不过,这个查询反而是 returns 0.


为了帮助我进行调试,我检查了另外两个查询。

首先,我尝试注释掉 WHERE 子句,它应该给我 所有 的 ContactID,无论它们是否为无效公司工作:

select
    count(ContactID)
from
    Contact

这个查询 returns 29722995.

其次,我尝试从我的查询中删除 NOT,这应该会给出与我正在寻找的相反的结果(即,它应该计算为 valid[=68= 工作的联系人] 家公司):

select
    count(ContactID)
from
    Contact
where
    CompanyID in
        (select
            CompanyID
        from
            Company)

这个查询 returns 26997457.


值得注意的是,这两个数字相差 恰好 2725538,第一个有效查询所输入的数字 return。如果我的第二个查询 工作,这就是我所期望的。联系人总数减去公司 table 中 CompanyID 的联系人数量,应等于 CompanyID 不是 [=] 的联系人数量68=]在公司table,不是吗?

那么,为什么 "not in" 版本的查询 return 是 0 而不是正确答案?

唯一的问题可能是 NULL 公司 ID。 Not In 不适用于 NULL,因为 NULL.

的不可比性

尝试以下操作:

select
    count(ContactID)
from
    Contact
where
    CompanyID not in
        (select
            ISNULL(CompanyID,'')
        from
            Company)

你可以在db<>fiddle中看到例子here.

请查找更多详细信息HERE