是什么导致这些看似不一致的查询结果?

时间:2012-10-04 15:22:57

标签: sql sql-server compare match record

我遇到了一个让我感到困惑的问题。我期待你们中的一个人指出我忽视的一些非常愚蠢的错误,但我真的没有看到它。

我有一张表,我们的生产过程已经为一年的时间提供了一些东西,我们只是从我们的客户那里获得了一些我们试图匹配数据的疯狂表格。在以下查询中,tableA是我的表格,tableB是我们刚刚导入的表格。

基本问题是

select *
from tableA
where convert(nvarchar(30),accountNum) not in (
        select CisAC
        from tableB
    )
当我认为它应该是

没有返回任何记录。我认为它应该在tableA中找到任何记录,其中accountNum匹配tableB中的CisAC字段。对? CisAC是一个nvarchar(30),我们的accountNum字段是一个bigint。

指出为什么我认为空回归集是错误的:

select * from tableA where convert(nvarchar(30),accountNum) = '336906210032'

返回一条记录,但

select * from tableB where CisAC = '336906210032'

没有。

那么,是什么给出的? (谢谢你的时间!)

3 个答案:

答案 0 :(得分:3)

我的怀疑是tableB中的空值导致IN失败

我会尝试

select * 
from tableA 
     left join tableB
     on convert(nvarchar(30),tableA.accountNum) = tableB.CisAC 
where tableB.CisAc is null

答案 1 :(得分:3)

您的查询是正确的。它正在返回预期的结果。

请参阅此处了解SQL小提琴:http://sqlfiddle.com/#!6/dfb5d/1

可能发生的情况是tableB中的数据与tableA中的数据不匹配。

编辑:

@Andomar回答说,如果tableB的值为空,则查询将失败。见这里:

http://sqlfiddle.com/#!6/05bb1/1

答案 2 :(得分:2)

这可能是经典的not in错误。如果表B包含任何null值,

where convert(nvarchar(30),accountNum) not in (
        select CisAC
        from tableB
    )

永远不会成功。你可以写出:

where convert(nvarchar(30),accountNum) <> null and convert(nvarchar(30),accountNum) <> ...

由于与null的任何比较都评估为unknown,因此这种情况永远不会成立。

用像podiluska的回答那样的join替换查询建议应该这样做。