我有一个SQL Server 2008 R2查询返回“假设”100行。我实际上正在使用7k - 8k行。
Where
子句是这样的:
Where Col_a = 'Y'
And Col_b = 'N'
And Col_c = 'X'
并且其中25行在Col_d
中有'P'。
我补充说:
And Col_d = 'P'
并且查询返回了预期的25行。
然后我改为
And Col_d <> 'P'
我预计会有75行,但我只有50行。
我认为添加“And Col_d <> 'P'
”只会限制'P'
中Col_d
的行。
为什么不是这种情况,当我说Col_d <> 'P'
时,我怎么弄清楚还有什么东西掉了?
正如我所说 - 我实际上是在处理更大的数字,因此观察它并不容易。
我很感激任何帮助。
谢谢!
答案 0 :(得分:5)
正如评论中所述,null
在进行比较时属于special case。
假设以下数据。
id someVal
----
0 null
1 1
2 2
查询:
select id
from table
where someVal = 1
将返回id 1
select id
from table
where someVal <> 1
将返回id 2
select id
from table
where someVal is null
将返回id 0
select id
from table
where someVal is not null
会返回ID 1
和2
。
如果你想要空值&#34;计算&#34;作为a =&lt;&gt;中的值比较,它需要被强制转换为:
select id
from table
where isNull(someVal, -1) <> 1
返回0
和2
或者您可以更改ANSI Null设置。
我想要做的只是排除那些有&#39; P&#39;在Col_d
因此,在您的特定情况下,由于您希望将Col_D中的null
视为非P
行,因此您的查询可能如下所示:
select *
from someTable
Where Col_a = 'Y'
And Col_b = 'N'
And Col_c = 'X'
And isNull(Col_D, 'someArbitraryValue') <> 'P'
您必须执行上述操作,因为正如我在整个答案和链接null
中所指出的那样,不会将值与值进行比较。您需要使null
非空的内容(使用isNull(Col_D, 'someArbitraryValue')
完成)或更改ANSI NULL
设置,以便将其与等值或不等于某个值进行比较。
或者@Andrew指出magic numbers是坏的(someArbitraryValue),所以你可以改为:
select *
from someTable
Where Col_a = 'Y'
And Col_b = 'N'
And Col_c = 'X'
And (Col_D <> 'P' OR Col_D is null)
通常情况下,我会直接进行上面的查询,我这样做是为了主要指出空值比较与值之间的差异。