SQL Server - 集合中的空值

时间:2016-03-27 17:48:47

标签: sql sql-server-2008

有人可以解释原因吗

 SELECT bl_id
  FROM bl
 WHERE bl_id NOT IN (SELECT bl_id FROM eq
                      WHERE bl_id IS NOT NULL)

返回1,483行。 但是,

 SELECT bl_id
  FROM bl
 WHERE bl_id NOT IN (SELECT bl_id FROM eq)

返回0行?

我意识到它与“SELECT bl_id FROM eq”可以返回一个可以为null的bl_id这一事实有关。

但我不明白的是,即使其中一个bl_id值为null,外部WHERE子句也永远不会返回true。为什么?

1 个答案:

答案 0 :(得分:4)

这就是NOT IN的工作原理。我强烈建议您学会使用NOT EXISTS代替:

SELECT bl_id
FROM bl
WHERE NOT EXISTS (SELECT 1
                  FROM eq
                  WHERE eq.bl_id = bl.bl_id
                 );

这具有您期望的语义。

原因是因为SQL中的NULL表示“未知”。 不是特定值。因此,如果你有这些:

where 1 not in (1, 2, 3)
where 1 not in (2, 3)

然后SQL可以将第一个评估为“false”,将第二个评估为“true”。但是,如果你有:

where 1 not in (1, 2, 3, NULL)
where 1 not in (2, 3, NULL)

然后第一个是“假”,因为“1”在集合中。第二个是NULL,因为我们不知道NULL可能是什么值,它可能是1。因此,子集中NOT INNULL始终返回“false”或NULL,这些可能性都不是真的。