【问题标题】:SQL Subquery Returning Strange ResultsSQL 子查询返回奇怪的结果
【发布时间】:2017-12-20 16:53:11
【问题描述】:

我正在用 MS SQL 编写一个非常简单的子查询,它返回了意外的结果。我试图返回的是一个存在于一个时间段但不存在于另一个时间段的账户号码列表。我的初始查询(粘贴在下面)返回了零行,这是意外的。

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 并获得相同的结果(使用转换而不是强制转换)。有人可以向我解释为什么查询一返回零结果而查询二返回预期结果吗?

我正在使用 Microsoft SQL Management Studio 2016。

谢谢

【问题讨论】:

  • 您能否展示示例数据来验证您在两个查询中看到的结果?
  • 您应该考虑对日期使用日期或日期时间数据类型,而不是整数。

标签: sql sql-server subquery sql-server-2016


【解决方案1】:

不要使用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
                 );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-06
    • 2014-12-31
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    • 2018-09-01
    • 1970-01-01
    相关资源
    最近更新 更多