NULL值被排除在外。为什么?

时间:2012-07-15 12:20:07

标签: sql sql-server sql-server-2008

这是我在Microsoft Sql Server中发现的奇怪行为。如果我错了,请纠正我。

SELECT COUNT(*) FROM TABLEA 
WHERE [Column1] IS NULL;

返回30018行。

CREATE VIEW VIEWB AS 
SELECT * FROM TABLEA AS t1 
WHERE t1.[Column1] NOT IN ('Cross/Up sell', 'Renegotiation', 'Renewal')  

如果我选中VIEWB,我在NULL中找不到Column1

SELECT COUNT(*) FROM VIEWB 
WHERE [Column1] IS NULL;

返回0行。

为什么呢?上面的查询排除了3个值,但不应该排除NULL 。为什么Sql Server Ms会以这种方式运行?我应该预料到这一点吗? 我该如何解决?

5 个答案:

答案 0 :(得分:15)

这实际上是SQL Server在将NULL视为值时所犯的常见错误。默认情况下,它被视为UNKNOWN,如文档here所示。因此,在您看来,您还需要添加OR t1.[Column1] IS NULL

您可以通过调用SET ANSI_NULLS OFF来更改此行为。但是,不建议使用此功能,因为@Martin Smith指出该功能已被弃用。

但这不是SQL Server特有的问题。它是ANSI SQL standard

的一部分

答案 1 :(得分:12)

SQL使用three valued logic

t1.[Column1] NOT IN ('Cross/Up sell', 'Renegotiation', 'Renewal') 

相当于

t1.[Column1] <> 'Cross/Up sell' AND  
t1.[Column1] <> 'Renegotiation' AND 
t1.[Column1] <>  'Renewal')

t1.[Column1] is NULL此表达式求值为UNKNOWN而不是TRUE时,不会返回这些行。

唯一的时间NULL NOT IN ( ... )将返回NOT IN子句评估为空集。

答案 2 :(得分:3)

最佳答案是在where子句

中使用以下条件

ISNULL(t1。[Column1],'') NOT IN('Cross / Up sell','Renegotiation','Renewal')

答案 3 :(得分:1)

在处理nulls

时要小心的另一个例子

我只是同意Sumo - 为什么不将视图更改为:

CREATE VIEW VIEWB AS 
SELECT * FROM TABLEA AS t1 
WHERE 
    t1.[Column1] NOT IN ('Cross/Up sell', 'Renegotiation', 'Renewal')  
    OR
    t1 IS NULL 

替代方案可能是我已添加到SQL FIDDLE

的以下内容
CREATE VIEW VIEWB AS 
SELECT * FROM TABLEA AS t1 
WHERE 
    1 = CASE 
          WHEN ISNULL(t1.[Column1],'x') NOT IN ('Cross/Up sell', 'Renegotiation', 'Renewal') THEN 1
          ELSE 0
        END

答案 4 :(得分:0)

确认这是SQL Server 2016的最佳解决方案

WHERE ISNULL(t1。[Column1],&#39;&#39;)NOT IN(&#39; Cross / Up sell&#39;,&#39; Renegotiation&#39;,&#39; Renewal& #39)