2010-11-18 60 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