2010-11-18 73 views
5

我创建了一些查询,无法理解为什么结果不符合我的预期。在SQL中使用NOT谓词

我不明白为什么查询II和III不会返回相同的结果。我希望查询II能够返回未由查询I选择的所有行。

我本来料想到查询II和III会给出相同的结果。在我看来,III的结果是正确的。

我敢肯定我错过了什么,我只是不知道该怎么做。

的例子:

表:

CREATE TABLE [dbo].[TestTable](
[TestTableId] [int] NOT NULL, 
    [ValueA] [int] NULL, 
[ValueB] [int] NULL 
) ON [PRIMARY] 

数据:

TestTableId ValueA ValueB 
1  10  5 
2  20  5 
3  10  NULL 
4  20  NULL 
5  NULL  10 
6  10  10 
7  NULL  NULL 

查询:

所有记录: SELECT * FROM TestTable的

一,选择查询:

select * from TestTable 
where (ValueA = 10 or ValueA = 20) AND ValueB = 5 

结果:

TestTableId ValueA ValueB 
1   10 5 
2   20 5 

II。同样的查询,但为NOT

select * from TestTable 
where NOT ((ValueA = 10 or ValueA = 20) AND ValueB = 5) 

结果:

TestTableId ValueA ValueB 
5   NULL 10 
6   10 NULL 

III。同样的查询作为第二(我想)

select * from TestTable where TestTable.TestTableId not in 
    (select TestTableId from TestTable 
where (ValueA = 10 or ValueA = 20) AND ValueB = 5) 

结果:

TestTableId ValueA ValueB 
3   10 NULL 
4   20 NULL 
5   NULL 10 
6   10 10 
7   NULL NULL 

回答

5

NULL的搞笑动物。他们会回答:“我不知道”,以同时满足以下两个问题:

Are you 5? (... WHERE ValueB = 5) 

Are you Not 5? (... WHERE NOT ValueB = 5) 

导致NULL值被排除两个查询,你发现了。

你必须要问的问题在明确占空值的方式:

... WHERE (ValueB IS NULL OR NOT ValueB = 5) ... 
+0

“NULL = 5”的计算结果为“UNKNOWN”(而不是“no”)。 – onedaywhen 2010-11-18 15:26:59

+0

我当时有点隐喻。重点是ValueB为NULL的行将被排除在外。 – BradC 2010-11-18 16:49:19

+0

@onedaywhen - 根据您的评论编辑我的文章,以稍微更精确。 – BradC 2010-11-18 19:02:46

2

当使用NOTNULL值是一个特殊情况。

A NULL未知值。 SQL不能说如果它是NOT一个12,但可以说它是一个12。

一个很好的例子:

你参加聚会。你知道房间里12个人的名字中有2个,都被命名为约翰。你可以告诉我“约翰”是谁。你不能告诉我谁是除了2“约翰”之外的“不是杰克”。对于SQL,房间里的其他10个人的名字是NULL