IS NULL与<> 1个SQL位

时间:2013-02-05 06:16:42

标签: sql sql-server null sql-server-2012

我在SQL Server 2012数据库的表上有一个列。

我正在尝试检索此位列为NULL或NOT TRUE的所有行。

此查询不会带回它应该的内容:(返回0行)

Select * 
from table 
where bit_column_value <> 1

此查询会返回正确的行:

Select * 
from table 
where bit_column_value IS NULL

现在,我很乐意使用第二个查询,但我的问题是,在另一个表的类似查询中,上面的反向是正确的,第一种方式有效,但第二种方式不!

有人可以协助解释上述内容的区别吗?我已经专门更新了相关的位列为NULL,这不会改变结果。 (可能认为“空”和Null值之间存在差异。

提前感谢任何解释。

5 个答案:

答案 0 :(得分:25)

<>不起作用的原因是SQL将NULL视为未知 - 它不知道NULL应该是什么意思,因此它会同时评估= <>上的NULLUNKNOWN OR(在where子句或连接条件中被视为false)。有关详细信息,请阅读:Why does NULL = NULL evaluate to false in SQL server

如果有索引,使用ISNULL函数将意味着索引无法使用,所以 确保查询可以使用索引只需使用SELECT * FROM TableName WHERE bit_column_value IS NULL OR bit_column_value = 0

{{1}}

答案 1 :(得分:7)

你最好的选择是写下这样的查询:

SELECT
     * 
FROM 
     table 
WHERE 
     ISNULL(bit_column_value, 0) = 0

这应该返回所有NULL和FALSE记录。

如果没有看到您的表格结构和数据,我无法评论为什么您从2个查询中得到不同的结果。

答案 2 :(得分:2)

MSDN表示BIT类型可以存储值0,1或NULL。 (BIT值为NULL的事实必须与位值本身分开存储,因为可以压缩位值,以便将8个BIT值存储在一个字节中。)

请记住WHERE子句中的条件在条​​件为TRUE时选择一行。对于大多数二元谓词(条件),如果将NULL与某个值进行比较,则结果为NULL或UNKNOWN(不为TRUE)。因此,例如,如果列中的值为NULL,则column = 0计算为NULL或UNKNOWN,column <> 0也是如此。

查看您的查询:

SELECT * FROM table WHERE bit_column_value <> 1

如果bit_column_value列中的值为1,则条件为FALSE,因此不返回该行;如果值为0,则条件为TRUE,因此返回行;如果值为NULL,则条件也为NULL或UNKNOWN,因此不返回该行。

SELECT * FROM table WHERE bit_column_value IS NULL

根据SQL标准,IS [NOT] NULL谓词和相关的IS [NOT] {TRUE | FALSE | UNKNOWN}谓词略有不同。如果测试值为NULL,则IS NULL测试返回TRUE;否则,它们返回FALSE(并且永远不会返回UNKNOWN)。 IS [NOT] {TRUE | FALSE | UNKNOWN}测试类似;如果值是指定类型,则返回TRUE,否则返回FALSE(不是UNKNOWN)。例如:

Column   IS TRUE   IS FALSE   IS UNKNOWN   IS NOT TRUE   IS NOT FALSE   IS NOT UNKNOWN
FALSE    FALSE     TRUE       FALSE        TRUE          FALSE          TRUE
TRUE     TRUE      FALSE      FALSE        FALSE         TRUE           TRUE
NULL     FALSE     FALSE      TRUE         TRUE          TRUE           FALSE

因此,在第二个查询中,只会选择bit_column_value值为NULL(与0和1分开)的行 - 不是TRUE,也不是FALSE。


  

我正在尝试检索此位列为NULL或NOT TRUE的所有行。

尝试直接从您的规范中编写查询:

  1. SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value IS NOT TRUE
  2. SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value = FALSE
  3. SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value <> TRUE
  4. SELECT * FROM table WHERE bit_column_value IS NOT TRUE
  5. 鉴于上面的真值表,查询4将产生您想要的结果 - 主要警告我不确定MS SQL Server是否支持IS [NOT] {TRUE | FALSE | UNKNOWN}。从Predicates上的MSDN判断,不支持IS [NOT] {TRUE | FALSE | UNKNOWN}谓词(但我可能错过了本手册的正确部分)。如果这是正确的,您需要使用查询2或3中的一个。


    (当这些谓词不是一个简单的列而是一个行值时,这些谓词有一些额外的复杂性。但是,这与你的问题或问题无关;加倍,因为MS SQL Server似乎不支持它们。 )

答案 3 :(得分:1)

请检查您的表数据,如果它包含值= 0?

SQL Bit data type只能有0,1或NULL的值,如果插入其他值,则认为是1(例外:如果插入'False',它将变为0 ,'True'将成为1)。

例如:

insert into t1 values (1),(2),(1),(3),(-1),(0),(NULL),('false'),('true')

结果:

  

1,1,1,1,1,0,NULL,0,1

答案 4 :(得分:1)

我认为这是因为此列中的所有数据都有NULL个值。所以:

Select * 
from table 
where bit_column_value <> 1;

不会给你结果。由于NULL未知。这个:

Select * 
from table 
where bit_column_value IS NULL;

将为您提供您正在寻找的结果。

但您误以为使用bit数据类型表示 true false

您将 false 表示为NULL0为空, true 是任何其他值。 bit数据类型的作用为@IswantoSan explained in his answer;它应该是0或1或NULL

  • 0是假的,
  • 1是真的,
  • NULL是空的。

因此得到:

  • true值使用where bit_column_value = 1
  • false值使用where bit_column_value = 0
  • NULL或空where bit_column_value IS NULL
  • NULL or not true:其中bit_column_value为NULL或bit_column_value = 0`。

另外需要注意的是NULL和空是两个不同的东西,它们不一样。如果BIT数据类型为空,则NULL不为0,因为0应该为假。但是考虑一下像VARCHAR这样的字符串数据类型,那么空字符串''NULL值完全不同。