21

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

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

此查询没有返回它应该返回的内容:(返回 0 行)

Select * 
from table 
where bit_column_value <> 1

此查询带回正确的行:

Select * 
from table 
where bit_column_value IS NULL

现在,我很乐意使用第二个查询,但我的问题是,在对另一个表的类似查询中,上述相反的情况是正确的,第一种方法有效,但第二种方法无效!

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

提前感谢您的任何解释。

4

5 回答 5

30

<>不起作用的原因是 SQL 将NULL其视为未知 - 它不知道NULL应该是什么意思,因此它对两者=<>一个NULL值进行评估UNKNOWN(在 where 子句或连接条件中被视为 false)。有关更多信息,请阅读:Why does NULL = NULL evaluate to false in SQL server

如果上面有索引,使用 ISNULL 函数将意味着无法使用索引,因此要确保查询可以使用索引,只需使用OR

SELECT * 
FROM TableName
WHERE
   bit_column_value IS NULL OR bit_column_value = 0
于 2013-02-05T06:37:53.700 回答
10

您最好的选择是这样编写查询:

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

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

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

于 2013-02-05T06:21:55.743 回答
3

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

请记住,当条件为 TRUE 时,WHERE 子句中的条件会选择一行。对于大多数二元谓词(条件),如果将 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

鉴于上面的真值表,查询 4 ​​将产生您想要的结果——主要的警告是我不确定 MS SQL Server 是否支持 IS [NOT] {TRUE|FALSE|UNKNOWN}。从 MSDN on Predicates判断,不支持 IS [NOT] {TRUE|FALSE|UNKNOWN} 谓词(但我可能错过了手册的正确部分)。如果正确,您需要使用查询 2 或 3 之一。


(当值不是简单的列而是行值时,这些谓词会有一些额外的复杂性。但是,这与您的问题或问题无关;由于 MS SQL Server 似乎不支持它们,因此更是如此。)

于 2013-02-05T07:27:46.557 回答
1

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

SQL Bit 数据类型的值只能是 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, 空值, 0, 1

于 2013-02-05T06:29:47.740 回答
1

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

Select * 
from table 
where bit_column_value <> 1;

不会给你结果的。既然NULL是未知数。和这个:

Select * 
from table 
where bit_column_value IS NULL;

会给你你正在寻找的结果。

但是您对使用数据类型表示真假有一个误解。bit

您将false表示为NULL,0是空的,而true是任何其他值。bit数据类型如@IswantoSan 在他的回答中解释的那样工作;它应该是 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

于 2013-02-05T06:38:07.693 回答