我有一个关于SQL语法的问题我无法找到答案(尽管我可能会完全搜索错误的东西)。
我有一张名为“nullable bit
”字段的会员,名为“HasDroppedOut
”。
我现在发现,如果我选择这样的成员:
SELECT * FROM Members WHERE HasDroppedOut<>'true'
或者像这样:
SELECT * FROM Members WHERE (HasDroppedOut IS NULL OR HasDroppedOut='false')
我得到了不同的结果。这是因为某些行包含IsDroppedOut列的NULL字段,并且它们在第一个查询中被排除,但是包含在第二个查询中。
任何人都可以解释为什么会这样吗?我在这里没有抓到什么方面?
答案 0 :(得分:1)
'true'
的反面不是{{1}}。 'false' OR NULL
值在概念上表示其值根本不知道的值。换句话说,我们不知道它是NULL
还是true
。因此,将false
和NULL
记录整合在一起是没有意义的。
更有意义的比较是等同于以下两个查询:
false
这两个查询都不会包含SELECT * FROM Members WHERE HasDroppedOut <> 'true'
SELECT * FROM Members WHERE HasDroppedOut = 'false'
条记录,因此这些NULL
条记录根本不会成为比较的一部分。
答案 1 :(得分:1)
与NULL
进行比较时,您必须使用IS (NOT) NULL
。如果您对NULL使用=
,<>
或!=
运算符,则返回结果为UNKNOWN。
考虑:
DECLARE @bit bit = NULL;
SELECT CASE @Bit WHEN 0 THEN 'Yes'
WHEN 1 THEN 'No'
ELSE 'Eh?'
END AS StatedValue,
CASE WHEN @Bit <> 1 THEN 'Yes'
WHEN @Bit <> 0 THEN 'No'
ELSE 'Eh?'
END AS UnstatedValue;
请注意,两者都返回值'Eh?'
,因为与NULL
的比较返回NULL。
因此,对于此示例,您需要执行以下操作:
DECLARE @bit bit = NULL;
SELECT CASE WHEN @Bit <> 1 THEN 'Yes'
WHEN @Bit <> 0 THEN 'No'
WHEN @Bit IS NULL THEN 'Neither'
ELSE 'Eh?'
END AS CheckedValue;