这是设计使然。如果匹配失败并且集合包含 NULL,则结果为 NULL,如 SQL 标准所指定。
'1' IN ('1', '3') => true
'2' IN ('1', '3') => false
'1' IN ('1', NULL) => true
'2' IN ('1', NULL) => NULL
'1' NOT IN ('1', '3') => false
'2' NOT IN ('1', '3') => true
'1' NOT IN ('1', NULL) => false
'2' NOT IN ('1', NULL) => NULL
通俗地说,其背后的逻辑是 NULL 可以被认为是一个未知值。例如,这里未知值是什么并不重要 - '1' 显然在集合中,所以结果是 true。
'1' IN ('1', NULL) => true
在下面的示例中,我们无法确定“2”是否在集合中,但由于我们不知道所有值,因此我们也无法确定它是否在集合中isn't在集合中。所以结果是NULL。
'2' IN ('1', NULL) => NULL
另一种看待它的方法是重写x NOT IN (Y, Z)
as X <> Y AND X <> Z
。然后你可以使用以下规则三值逻辑 http://en.wikipedia.org/wiki/Null_%28SQL%29#Three-valued_logic_.283VL.29:
true AND NULL => NULL
false AND NULL => false