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

Sam*_*Sam 20 sql sql-server sql-server-2008

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

SELECT COUNT(*) FROM TABLEA 
WHERE [Column1] IS NULL;
Run Code Online (Sandbox Code Playgroud)

这将返回30018行.

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

如果我检查VIEWB,我不觉得NULLColumn1:

SELECT COUNT(*) FROM VIEWB 
WHERE [Column1] IS NULL;
Run Code Online (Sandbox Code Playgroud)

这将返回0行.

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

Sum*_*umo 18

这实际上是SQL Server在将NULL视为值时所犯的常见错误.默认情况下,它被视为UNKNOWN,如此处所述.因此,在您看来,您还需要包含一个OR t1.[Column1] IS NULL.

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

但是,这不是SQL Server特定的问题.它是ANSI SQL标准的一部分.

  • `SET ANSI_NULLS OFF`值得一提,但是已弃用并在文档中有以下警告.`避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序 (4认同)

Mar*_*ith 12

SQL使用三值逻辑.

t1.[Column1] NOT IN ('Cross/Up sell', 'Renegotiation', 'Renewal') 
Run Code Online (Sandbox Code Playgroud)

相当于

t1.[Column1] <> 'Cross/Up sell' AND  
t1.[Column1] <> 'Renegotiation' AND 
t1.[Column1] <>  'Renewal')
Run Code Online (Sandbox Code Playgroud)

t1.[Column1] is NULL此表达式求值UNKNOWNTRUE不是返回时,不返回这些行.

NULL NOT IN ( ... )如果NOT IN子句求值为空集,则返回的唯一时间.

  • @MikeFulton - 当column1为"NULL"时,它被视为未知,无论它是否为其中一个值.SQL使用`TRUE/FALSE/UNKNOWN`.`WHERE`子句仅返回谓词计算结果为true的行. (3认同)

小智 6

最佳答案是在 where 子句中使用以下条件

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