The NOT IN Trap
SELECT x FROM (VALUES (1), (2), (3)) AS a(x)
WHERE x NOT IN (2, NULL);
- Zero rows! Is 1 equal to
NULL? Unknown, so 1 NOT IN (2, NULL) is not true
- One
NULL anywhere in the list, and NOT IN returns nothing
- It is also slow: PostgreSQL can't use a hash table, so it compares every pair
IN doesn't have this problem, only NOT IN
Remember: use NOT IN only on a column that can't be NULL, like a primary key; otherwise use NOT EXISTS