我在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
值之间存在差异。
提前感谢任何解释。
答案 0 :(得分:25)
<>
不起作用的原因是SQL将NULL
视为未知 - 它不知道NULL
应该是什么意思,因此它会同时评估=
<>
上的NULL
和UNKNOWN
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的所有行。
尝试直接从您的规范中编写查询:
SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value IS NOT TRUE
SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value = FALSE
SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value <> TRUE
SELECT * FROM table WHERE bit_column_value IS NOT TRUE
鉴于上面的真值表,查询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 表示为NULL
,0
为空, true 是任何其他值。 bit
数据类型的作用为@IswantoSan explained in his answer;它应该是0或1或NULL
:
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
值完全不同。