select
-- simple things
1 = 1, -- true
1 = 2, -- false
-- "simple things" with null
1 = null, -- null (and it is not `false` if you expected this)
1 != null, -- null (and it is not `true` if you expected this)
-- "strange" area:
null = null, -- null (and it is not `true` and not `false`)
null != null, -- null (and it is not `true` and not `false`)
1 > null, -- null (yeah, after 4 previous examples it is exactly what you expected)
1 < null, -- null
null < null, -- null
null > null, -- null
-- value IN ()
1 in (1,2), -- true
1 in (1,null), -- true
1 in (2, 3), -- false
1 in (2, null), -- null (!!! surprise?)
3 between (1, NLL),-- null
-- value NOT IN
1 not in (1,2), -- false
1 not in (1,null), -- false
1 not in (2, 3), -- true
1 not in (2, null), -- null (!!! surprise?)
-- NULL IN/NOT IN
null in (1,2), -- null
null in (NULL), -- null
null not in (1,2), -- null
null not in (NULL), -- null
-- and surprise:
NOT NULL -- NULL (!!, but most probably you foresaw/knew this)
6条答案
按热度按时间p4tfgftt1#
[not] in (null)
的结果将始终为null。要与null进行比较,需要is [not] null
或is [not] distinct from null
如果你想要
where (ID not in (1,null))
在你的评论,你可以这样做knsnq2tg2#
PostgreSQL使用NULL作为未定义的值。
您所要求的是返回不在列表中的项或未定义的值。因为undefined意味着你不知道里面是什么,PostgreSQL不返回任何项,因为它根本无法响应请求。
而请求:
可以返回记录,因为如果它找到ID = 1的元素,就知道它在集合中
请求:
不能满足,因为空值可以是任何值。
t98cgbkg3#
回答
解决方案已经发布了dx 1 e0f1x,我的解决方案几乎相同:
别忘了,条件的反转版本(
is null or in (list)
)使用了OR
-运算符(而不是AND
):奖励:SQL和NULL
这是一个好的SQL开发人员在潜意识区域的某个地方有一件事(请求在Postgres中进行了测试,但我很确定它是标准ANSI SQL的行为):
正如你所看到的,如果
null
是一个操作数,那么结果是null
,在布尔上下文中(例如,在WHERE
-子句中),它是 falsey。但是,falsey 和 false 不一样,NOT (1=NULL)
是NULL,而不是truly
,所以这两个请求都返回0行:希望有用
dhxwm5r44#
我也遇到过类似的in问题,最终想出了以下解决方案;
返回Name列为空的记录。也可以用于not in子句,返回Name的非空记录;
csga3l585#
我也有类似的问题。我的自尊心,我知道SQL很好,被刺穿了。下面是scott/tiger表的简化示例。
什么也没回。虽然我非常谨慎地使用NOT IN condition,因为它不使用索引并且非常慢。我更喜欢使用OUTER JOIN。
我在Postgres和Oracle中都试过这个查询,结果是一样的。因此,必须是符合标准的结果。NULL仅在NOT IN条件下才有这种行为。
vptzau2j6#
可以使用<> ANY操作符。代码示例: