【发布时间】:2013-07-26 11:20:18
【问题描述】:
我在这个查询中使用 Postgres
select
*
from Entity this_
where
(this_.ID not in (null))
为什么这没有给我任何结果?我希望得到所有 id 不为空的行
与
(this_.ID not in (1))
我得到了预期的结果
【问题讨论】:
标签: postgresql null notin
我在这个查询中使用 Postgres
select
*
from Entity this_
where
(this_.ID not in (null))
为什么这没有给我任何结果?我希望得到所有 id 不为空的行
与
(this_.ID not in (1))
我得到了预期的结果
【问题讨论】:
标签: postgresql null notin
[not] in (null) 的结果将始终为空。要与 null 进行比较,您需要 is [not] null 或 is [not] distinct from null
select *
from Entity this_
where this_.ID is not null
如果你想要where (ID not in (1,null)),就像你的评论一样,你可以这样做
where ID is not null and ID not in (1)
【讨论】:
PostgreSQL 使用 NULL 作为未定义的值。
您要求的是返回不在列表中或未定义值中的项目。由于 undefined 意味着你不知道里面有什么,PostgreSQL 不会返回任何项目,因为根本无法响应请求。
而请求:
select * from Entity where id in (1, null)
可以返回记录,因为如果它找到一个 ID = 1 的元素就知道它在集合中
请求:
select * from Entity where (ID not in (1, null))
不能满足,因为空值可以是任意值。
【讨论】:
NULL 是NULL,而不是任何值。这是一个特殊值,但绝对不是ANY 值。实际上,对我而言,记住以下内容就足够了:where null = null - 返回 0 行,where null != null - 0 行,null > null - 零行,几乎所有其他以 NULL 作为参数的操作都返回 false我>。所有这些都适用于 IN-operator (因为它基本上与将 == 项目与 ( parentheses - list ) 中的每个元素进行比较几乎相同)。
解决方案已经发布in this answer,我的解决方案也差不多:
where
"field" is NOT NULL
AND "field" not in (1)
不要忘记,条件的反转版本 (is null or in (list)) 使用 OR-运算符(而不是 AND):
where
"field" is NULL
OR "field" in (1)
这是一个优秀的 SQL 开发人员在潜意识中的某个地方(该请求已在 Postgres 中测试过,但我很确定这是标准 ANSI SQL 的行为):
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
-- 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
-- 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)
如您所见 - 如果 null 是操作数,则结果为 null 并且在布尔上下文中(例如,在 WHERE 子句中) - 它是 falsey .虽然,falsey 和 false 不一样,NOT (1=NULL) 是 NULL,但不是 truly,所以这两个请求都返回 0 行:
-- 1
select 1 where (1 = null)
-- 2
select 1 where NOT (1 = null)
希望对你有用
【讨论】:
select *
from Entity this_
where (this_.ID not in (null))
“IN”或“NOT IN”不选择 NULL 值 你可以写
select *
from Entity this_
where (this_.ID not in (1))
而且您的选择不会包含空值
【讨论】:
我也遇到过类似的in问题,最终想出了以下解决方案;
select * from public."Employee_11" where (COALESCE("Name",'@'),"Surname")
in (
('@','dummy')
)
它确实返回 Name 列具有空值的记录。您也可以将此用于 not in 子句,该子句将返回 Name 的非空记录;
select * from public."Employee_11" where (COALESCE("Name",'@'),"Surname")
not in (
('@','dummy')
)
【讨论】:
我有类似的问题。我对 SQL 很了解的自尊心被戳破了。 这是 scott/tiger 表中的简化示例。
select empno, ename from emp where deptno not in (10, 20, null);
什么也没返回。尽管我非常谨慎地使用 NOT IN 条件,因为它不使用索引并且非常慢。我更喜欢使用 OUTER JOIN 代替。
我在 Postgres 和 Oracle 中都试过这个查询,结果是一样的。因此,必须是符合标准的结果。 NULL 仅在 NOT IN 条件下才会如此。
【讨论】:
deptno not in (10, 20, null); 与 detpno <> 10 AND detpno <> 20 AND deptno <> NULL 相同(例如,对于 detpno=1)与 false AND false AND null 相同,而 NULL 又是 WHERE 子句的“不正确”。结果与deptno 的值无关,因此对于表中的所有行它都是“不正确的”,因此它什么也不返回。
您可以使用 ANY 运算符。 您的代码示例:
select
*
from Entity this_
where
(this_.ID <> ANY (null))
【讨论】: