我有一个表有一列值可以是rowTypeID =(1,2,3或null)。我想编写一个查询,返回任何没有值为3的行。在这个例子中,我想要所有NULL行以及所有1,2行,我只是不希望行值为3
当前为数据库设置了ANSI null ON。
我很好奇为什么我不能写
select * from myTable where myCol <> 3
此查询不会返回myCol列中具有NULL的任何行
我必须写
select * from my Table where myCol <> 3 or myCol Is NULL
我是否总是必须包含IS NULL或者我可以设置它以使where子句myCol&lt;&gt; 3将返回具有Null作为我的Col的值的行
答案 0 :(得分:15)
我认为你的方法很好:
SELECT *
FROM MyTable
WHERE myCol <> 3 OR myCol IS NULL
由于您要求替代方法,另一种方法是创建列NOT NULL
并在数据库中存储另一个(其他未使用的)值而不是NULL
- 例如{{1} }。然后,表达式-1
将与您的假名myCol <> 3
匹配,就像处理任何其他值一样。
NULL
但总的来说,我会建议不来使用此方法。你已经采取的方式是正确的方式。
另外值得一提的是,其他几个数据库支持SELECT *
FROM MyTable
WHERE myCol <> 3
,它完全符合您的要求:
IS DISTINCT FROM
MySQL有NULL-safe equal也可以用于此目的:
SELECT *
FROM MyTable
WHERE myCol IS DISTINCT FROM 3
不幸的是,SQL Server还不支持这两种语法。
答案 1 :(得分:3)
您必须以这种或那种方式处理NULL,因为涉及NULL
evaluate to Unknown的表达式。如果你愿意,你可以改为:
select *
from MyTable
where isnull(MyColumn, -1) <> 3
但是这涉及一个幻数(-1),可以说比IS NULL
的原始测试可读性低。
编辑,并且正如SQLMenace指出的那样,不是SARGable。
答案 2 :(得分:2)
每当你测试一个值时,所有的NULL都被省略 - 毕竟,你正在测试某些列中的值是否通过了某些条件而NULL是而不是值。
答案 3 :(得分:1)
我是否总是必须包含IS NULL或者我可以设置它以使where子句myCol&lt;&gt; 3将返回具有Null作为我的Col的值的行?
您总是,始终,始终必须包含is null
。
因为3不等于Not / Applicable并且它不等于Unkown。
答案 4 :(得分:0)
因为你无法将NULL与其他任何东西进行比较,所以NULL甚至不等于NULL
DECLARE @i INT
DECLARE @i2 INT
SELECT @i = NULL, @i2 = NULL
IF @i = @i2
PRINT 'equal'
ELSE
PRINT 'not equal'