为什么这两个查询产生不同的结果?

时间:2019-02-20 00:22:46

标签: sql tsql null

我正在尝试查找不在申请表中的人数。

我有两个表( person和application ),其中人与应用程序( person.id = application.person )具有一对多关系。但是,一个人可能没有申请。应用程序表中大约有35,000条记录。为了这篇文章,我能够减少查询并仍然产生问题。我希望第一个查询产生与第二个查询相同数量的结果,但是不会。

此查询为什么会产生零结果:

select count(*) 
from person p where (p.id not in (
    select person
    from application 
))

此查询产生预期结果时:

select count(*) 
from person p where (p.id not in (
    select person
    from application 
    where person=p.id 
))

根据我的理解,第二个查询是正确的,因为:

  1. 当人没有应用程序时,内部选择返回null,其中p.id not in null返回true
  2. 当某人拥有应用程序时,内部选择返回应用程序p.id,其中app p.id not in p.id返回false

但是,我不明白为什么第一个查询不等于第二个查询。

有人可以解释一下(非常感谢)吗?

1 个答案:

答案 0 :(得分:0)

您不应将not in与子查询一起使用。它无法正确(或至少直观地)对待NULL值。而是用not exists来表示查询:

select count(*) 
from person p
where not exists (select 1
                  from application a
                  where a.person = p.id 
                 );

对于NOT IN,如果子查询中的 any 行返回NULL,则外部查询根本不会返回任何行。

您的带有相关性子句的版本限制了损坏。但是,我的建议是仅使用NOT EXISTS