Postgres NOT IN (null) gives no result
answer
The solution was already postedanother answer, but the same page, and my solution is almost the same:
where
"field" is NOT NULL
AND "field" not in (1)
don't forget, the inverted version of the condition (is null or in (list)
) uses the OR
-operator (instead of AND
):
where
"field" is NULL
OR "field" in (1)
bonus: SQL and NULL
and here is a thing a good SQL-developer has somewhere in the subconscious zone (the request was tested in Postgres, but I'm pretty sure it is the behavior from the standard 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?)
-- 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)
as you can see - if the null
is an operand then the result is null
and in a boolean context (for example, in WHERE
-clauses) - it is falsey. Though, falsey is not the same as false, and NOT (1=NULL)
is NULL, but not truly
, so both these requests return 0 lines:
-- 1
select 1 where (1 = null)
-- 2
select 1 where NOT (1 = null)
I hope it was useful
PostgreSQL uses NULL as undefined value.
What you're asking is to return the items that are not in a list or an undefined value. Since undefined means that you do not know what's inside, PostgreSQL does not return any item because simply can not respond to the request.
While the request:
select * from Entity where id in (1, null)
can return the records, because if it finds an element with ID = 1 knows that is in the collection
the request:
select * from Entity where (ID not in (1, null))
can not be satisfied because the null value can be any value.
The result of [not] in (null)
will always be null. To compare to null you need is [not] null
or is [not] distinct from null
select *
from Entity this_
where this_.ID is not null
If you want where (ID not in (1,null))
as in your comment you can do
where ID is not null and ID not in (1)