我在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。
由于
答案 0 :(得分:3)
不要使用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
);