NOT IN 过滤掉 NULL 值

NOT IN filter out NULL values

我试图从 table sample 中过滤掉一些预定义的值,其中有两列 col1col2.

我的查询:

select *
from sample
where (col1 is not null or col2 is not null)
and col1 not in (1,2)
and col2 not in (3,4);

但是,上面的查询过滤掉了所有空值(在 col1 或 col2 中)。

示例:以下行被过滤掉,

col1 col2
---------
7 null
null 8

当我将查询修改为以下时,我得到了预期的结果。

select *
from sample
where (col1 is not null or col2 is not null)
and (col1 not in (1,2) or col1 is null)
and (col2 not in (3,4) or col2 is null);

为什么 NOT IN 过滤掉具有 NULL 值的行,即使我没有在 NOT IN 中指定 NULL

不等于 NULL,不等于 NULL。对于像 NULL NOT IN (1,2) 这样的表达式,它的计算结果为 unknown,这(重要的)是 not true;意思是 WHERE 不满足。这就是为什么您处理 NULLs 的第二个查询有效。

或者,您可以使用 EXISTS。它可能不直观,但可以处理 NULL 个值:

WITH VTE AS(
    SELECT *
    FROM (VALUES(1,3),(2,4),(3,5),(7,NULL),(NULL,8))V(col1,col2))
SELECT *
FROM VTE
WHERE NOT EXISTS(SELECT 1
                 WHERE Col1 IN (1,2)
                   AND Col2 IN (3,4));

试试这个

SET ANSI_NULLS OFF
select *
from sample
where (col1 is not null or col2 is not null)
and col1 not in (1,2)
and col2 not in (3,4);

A​​NSI 空 ON/OFF: 此选项指定 ANSI NULL 比较的设置。启用时,任何将值与空值进行比较的查询 returns 为 0。关闭时,任何将值与空值进行比较的查询 returns 为空值 (https://blog.sqlauthority.com/2007/03/05/sql-server-quoted_identifier-onoff-and-ansi_null-onoff-explanation/#:~:text=ANSI%20NULL%20ON%2FOFF%3A,null%20returns%20a%20null%20value.)。

这在

中讨论过