postgresql Postgres NOT IN(null)没有结果

dohp0rv5  于 2023-05-28  发布在  PostgreSQL
关注(0)|答案(6)|浏览(307)

我使用Postgres查询

select 
*
from Entity this_ 
where 
(this_.ID not in (null))

为什么这给予我没有结果?我希望得到id不为null的所有行

(this_.ID not in (1))

我得到了预期的结果

p4tfgftt

p4tfgftt1#

[not] in (null)的结果将始终为null。要与null进行比较,需要is [not] nullis [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)
knsnq2tg

knsnq2tg2#

PostgreSQL使用NULL作为未定义的值。
您所要求的是返回不在列表中的项或未定义的值。因为undefined意味着你不知道里面是什么,PostgreSQL不返回任何项,因为它根本无法响应请求。
而请求:

select * from Entity where id in (1, null)

可以返回记录,因为如果它找到ID = 1的元素,就知道它在集合中
请求:

select * from Entity where (ID not in (1, null))

不能满足,因为空值可以是任何值。

t98cgbkg

t98cgbkg3#

回答

解决方案已经发布了dx 1 e0f1x,我的解决方案几乎相同:

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和NULL

这是一个好的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 (!!! 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)

正如你所看到的,如果null是一个操作数,那么结果是null,在布尔上下文中(例如,在WHERE-子句中),它是 falsey。但是,falseyfalse 不一样,NOT (1=NULL)是NULL,而不是truly,所以这两个请求都返回0行:

-- 1
select 1 where (1 = null)
-- 2
select 1 where NOT (1 = null)

希望有用

dhxwm5r4

dhxwm5r44#

我也遇到过类似的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')
        )
csga3l58

csga3l585#

我也有类似的问题。我的自尊心,我知道SQL很好,被刺穿了。下面是scott/tiger表的简化示例。

select empno, ename from emp where deptno not in (10, 20, null);

什么也没回。虽然我非常谨慎地使用NOT IN condition,因为它不使用索引并且非常慢。我更喜欢使用OUTER JOIN。
我在Postgres和Oracle中都试过这个查询,结果是一样的。因此,必须是符合标准的结果。NULL仅在NOT IN条件下才有这种行为。

vptzau2j

vptzau2j6#

可以使用<> ANY操作符。代码示例:

select 
  * 
from Entity this_ 
where 
   (this_.ID <> ANY (null))

相关问题