SQL子查询返回奇怪的结果

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL子查询返回奇怪的结果相关的知识,希望对你有一定的参考价值。

我正在MS SQL中编写一个非常简单的子查询,它会返回意外的结果。我想要返回的是一个存在于一个时间段但不存在于另一个时间段的acct数列表。我的初始查询(粘贴在下面)返回零行,这是意外的。

select
    name1.acct
from
    sym.dbo.name as name1
where
    name1.processdate = 20171130
    and name1.type = 0
    and name1.acct not in
    (
    select 
        name2.acct
    from 
        sym.dbo.name as name2
    where
        name2.type = 0
        and name2.processdate = 20171031
    )

但是,当我向子查询添加一行额外的逻辑并执行预期结果时,会返回给我,请参阅下文。

select
    name1.acct
from
    sym.dbo.name as name1
where
    name1.processdate = 20171130
    and name1.type = 0
    and name1.acct not in
    (
    select 
        name2.acct
    from 
        sym.dbo.name as name2
    where
        name2.type = 0
        and name2.processdate = 20171031
        and name2.acct <> '8888888'
    )

最初我认为它可能与数据类型有关,所以我尝试将acct编号转换为varchar和int,结果相同(使用convert而不是cast)。有人可以向我解释为什么查询一个返回零结果和查询两个返回预期结果?

我正在使用Microsoft SQL Management Studio 2016。

谢谢

答案

不要使用NOT IN,尤其是子查询。它的行为并不像预期的那样 - 正如您刚刚学到的那样。问题?如果子查询返回的任何值是NULL,那么NOT IN会过滤掉所有内容。

相反,使用NOT EXISTS

where name1.processdate = 20171130 and
      name1.type = 0 and
      not exists (select 1
                  from sym.dbo.name name2
                  where name2.acct = name1.acct and
                        name2.processdate = 20171031
                 );

以上是关于SQL子查询返回奇怪的结果的主要内容,如果未能解决你的问题,请参考以下文章

SQL 查询返回无意义的结果

MYSQL 查询不返回 BETWEEN 的结果,但它返回小于和等于子查询的结果

有层级的,怎么用sql查询返回结果

sql怎么用查询结果作为条件进行查询

SQL 子查询

sql提示子查询返回的值不止一个,求解如何修改,谢谢。