SQL Server:可空位,为什么字段'true'不能按预期工作?

SQL Server:可空位,为什么字段'true'不能按预期工作?,sql,sql-server,Sql,Sql Server,我有一个关于SQL语法的问题,我还没有找到答案,尽管我可能在搜索错误的东西 我有一个名为Members的表,它有一个名为hasdroppeddout的可空位字段 我现在发现,如果我选择这样的成员: SELECT * FROM Members WHERE HasDroppedOut<>'true' SELECT * FROM Members WHERE (HasDroppedOut IS NULL OR HasDroppedOut='false') 我得到了不同的结果。这是因为有些

我有一个关于SQL语法的问题,我还没有找到答案,尽管我可能在搜索错误的东西

我有一个名为Members的表,它有一个名为hasdroppeddout的可空位字段

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

SELECT * FROM Members WHERE HasDroppedOut<>'true'
SELECT * FROM Members WHERE (HasDroppedOut IS NULL OR HasDroppedOut='false')
我得到了不同的结果。这是因为有些行包含IsDroppedOut列的空字段,它们在第一个查询中被排除,但在第二个查询中被包括

有人能解释一下为什么会这样吗?这里我没有领会到什么方面?

与“真”相对的不是“假”或空。空值在概念上表示其值完全未知的值。换句话说,我们不知道这是真是假。因此,将空记录和假记录混为一谈是没有意义的

一个更有意义的比较是将以下两个查询等同起来:

SELECT * FROM Members WHERE HasDroppedOut <> 'true'
SELECT * FROM Members WHERE HasDroppedOut = 'false'
这两个查询都不包含空记录,因此这些空记录根本不属于比较的一部分。

当与必须使用的空记录进行比较时,它不是空的。如果使用a=,或!=运算符,返回的结果未知

考虑:

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;

删除where子句的结束括号并检查OP的问题是为什么列'True'和列为NULL或列='False'产生不同的结果。原因是表达式列'True'在值为NULL的情况下不返回True,其中as列为NULL或Column='False'返回True。我明白了……我并没有这样想:-对于OP的环境,答案很可能是NULL可以被归类为False。这并不总是正确的,但我可以举一个很好的例子。在我们的办公室,我们可以选择让客户为我们接受营销。在网站上,必须勾选或取消勾选,这将导致位列中的值为1或0,但如果通过电话与客户交谈,则必须询问客户。如果操作员没有询问,屏幕上的字段将留空,而不是“是”或“否”。在这种情况下,正如我们没有询问的那样,NULL被视为0,即使它们不是相同的值。@Larnu很有趣,但OP在问题中没有给出这样的上下文。我知道他们没有,该评论是对您关于NULL和FALSE不应混为一谈的评论的回应。他们肯定会有这样的时刻;最重要的是你对这些数据有一定的了解。在某些环境中,NULL本身可以具有已知值。我并不是说你的答案是错的;你说得对,NULL和true不一样。我只是补充了更多的信息,这也许可以解释OP的思考过程,并且两者可以被视为相等。@Larnu虽然你的一些评论可能是对的,但我认为你回答这个问题太多了。OP中的困惑似乎只是关于NULL代表什么,而不是你公司的网站是否在逻辑上决定将NULL和false视为同一事物。在SQL Server中,它们不是同一件事。我一点也不怀疑这一点。只是多加了2美分
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;