SQL Server:Nullable位,为什么字段<>'true'不按预期工作?

时间:2017-12-27 09:51:49

标签: sql sql-server

我有一个关于SQL语法的问题我无法找到答案(尽管我可能会完全搜索错误的东西)。

我有一张名为“nullable bit”字段的会员,名为“HasDroppedOut”。

我现在发现,如果我选择这样的成员:

SELECT * FROM Members WHERE HasDroppedOut<>'true'

或者像这样:

SELECT * FROM Members WHERE (HasDroppedOut IS NULL OR HasDroppedOut='false')

我得到了不同的结果。这是因为某些行包含IsDroppedOut列的NULL字段,并且它们在第一个查询中被排除,但是包含在第二个查询中。

任何人都可以解释为什么会这样吗?我在这里没有抓到什么方面?

2 个答案:

答案 0 :(得分:1)

'true'的反面不是{​​{1}}。 'false' OR NULL值在概念上表示其值根本不知道的值。换句话说,我们不知道它是NULL还是true。因此,将falseNULL记录整合在一起是没有意义的。

更有意义的比较是等同于以下两个查询:

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;