我有以下示例数据。
此查询返回我需要的数据:
select * from #temp
where (Field1 = 'Test1' or Field1 = 'Test10') and
Field2 = 'Test2' and
(Field3 = 'Test3' or Field3 = 'Test30')
但是,我需要另一个查询,该查询基本上显示不满足上述条件的记录(异常查询)。
如果我使用以下查询,则不会显示NULL值。这是为什么?如何获取带有NULL值的行以显示?
select * from #temp
where NOT (Field1 = 'Test1' or Field1 = 'Test10') and NOT
Field2 = 'Test2' and NOT
(Field3 = 'Test3' or Field3 = 'Test30')
Create Table #temp
(
ID int,
Field1 varchar(50),
Field2 varchar(50),
Field3 varchar(50)
)
Insert into #temp
(
ID,
Field1,
Field2,
Field3
)
select
1,
'Test1',
'Test2',
'Test3'
union all
select
2,
NULL,
NULL,
NULL
union all
select
3,
'Test',
'Test',
'Test'
答案 0 :(得分:3)
几乎所有与NULL
的比较都返回NULL
,这被视为错误。
一种相当昂贵的方法是使用EXCEPT
:
select t.*
from #temp t
except
select t.*
from #temp t
where (Field1 = 'Test1' or Field1 = 'Test10') and
Field2 = 'Test2' and
(Field3 = 'Test3' or Field3 = 'Test30');
请注意,这将消除重复的行。
我将条款简化为:
where Field1 in ('Test1', 'Test10') and
Field2 = 'Test2' and
Field3 in ('Test3', 'Test30');
很显然,您可以重构where
子句以将null
的值考虑在内。这确实很麻烦并且容易出错。因此,另一种方法是创建一个标志并仅使用该标志:
select t.*
from #temp t cross apply
(values (case when (Field1 = 'Test1' or Field1 = 'Test10') and
Field2 = 'Test2' and
(Field3 = 'Test3' or Field3 = 'Test30')
then 1 else 0
end)
) v(flag)
然后:
where v.flag = 1 -- for inclusion
where v.flag = 0 -- for exclusion
答案 1 :(得分:1)
NULL不等于任何值,也不不同于任何值。他们是未知的。
要处理空值,可以使用IS NULL和IS NOT NULL。
SELECT * FROM #temp
WHERE (
Field1 NOT IN ('Test1', 'Test10')
OR Field1 IS NULL)
AND (Field2 <> 'Test2' OR Field2 IS NULL)
AND (Field3 NOT IN ('Test3', 'Test30')
OR Field3 IS NULL)
作为一个额外的提示,您可以更改
Field1 = 'Test1' or Field1 = 'Test10'
对于
Field1 IN ('Test1', 'Test10')