在SQL中使用NOT谓词

Gab*_*iël 5 sql t-sql

我创建了一些查询,无法理解为什么结果不像我预期的那样.

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

我希望查询II和III能够给出相同的结果.在我看来,III的结果是正确的.

我确定我错过了什么,我只是不知道是什么.

这个例子:

表:

CREATE TABLE [dbo].[TestTable](
 [TestTableId] [int] NOT NULL,
    [ValueA] [int] NULL,
 [ValueB] [int] NULL
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

数据:

TestTableId ValueA ValueB
1        10      5
2        20      5
3        10      NULL
4        20        NULL
5        NULL      10
6        10        10
7        NULL      NULL
Run Code Online (Sandbox Code Playgroud)

查询:

所有记录:从TestTable中选择*

I.选择查询:

select * from TestTable 
where (ValueA = 10 or ValueA = 20) AND ValueB = 5
Run Code Online (Sandbox Code Playgroud)

结果:

TestTableId ValueA ValueB
1           10   5
2           20   5
Run Code Online (Sandbox Code Playgroud)

II.相同的查询,但不是

select * from TestTable 
where NOT ((ValueA = 10 or ValueA = 20) AND ValueB = 5)
Run Code Online (Sandbox Code Playgroud)

结果:

TestTableId ValueA ValueB
5           NULL   10
6           10   NULL
Run Code Online (Sandbox Code Playgroud)

III.与第二个相同的查询(我想)

select * from TestTable where TestTable.TestTableId not in 
    (select TestTableId from TestTable 
where (ValueA = 10 or ValueA = 20) AND ValueB = 5)
Run Code Online (Sandbox Code Playgroud)

结果:

TestTableId ValueA ValueB
3           10   NULL
4           20   NULL
5           NULL   10
6           10   10
7           NULL   NULL
Run Code Online (Sandbox Code Playgroud)

Bra*_*adC 5

NULL是有趣的生物.他们会对以下两个问题回答"我不知道":

Are you 5?  (... WHERE ValueB = 5)
Run Code Online (Sandbox Code Playgroud)

Are you Not 5? (... WHERE NOT ValueB = 5)
Run Code Online (Sandbox Code Playgroud)

如您所见,这会导致从两个查询中排除NULL值.

您必须以明确解释NULL的方式提出问题:

... WHERE (ValueB IS NULL OR NOT ValueB = 5) ...
Run Code Online (Sandbox Code Playgroud)