snippetsqlMinor
How to understand "NULL NOT IN" when the set is empty?
Viewed 0 times
thehownullemptyunderstandwhennotset
Problem
The SQL in this question is for Oracle. But you can simply remove
I have the following SQL:
which returns an empty set and 1 respectively. When we substitute some other value for
So how does the comparison between NULL and the empty result set work here?
FROM dual to make it work on SQL Server (which returns the same result as Oracle). I have the following SQL:
SELECT 1
FROM dual
WHERE NULL IN (SELECT 1 FROM dual WHERE 1 = 0);
SELECT 1
FROM dual
WHERE NULL NOT IN (SELECT 1 FROM dual WHERE 1 = 0);which returns an empty set and 1 respectively. When we substitute some other value for
NULL, we got the exact same result. SELECT 1
FROM dual
WHERE 33 IN (SELECT 1 FROM dual WHERE 1 = 0);
SELECT 1
FROM dual
WHERE 33 NOT IN (SELECT 1 FROM dual WHERE 1 = 0);So how does the comparison between NULL and the empty result set work here?
Solution
Lets see what happens with these two conditions:
since the subquery yields an empty table, we can write them in pseudocode:
So the first asks whether some (NULL) value is IN an empty table. The result of such condition is always
Applying the same reasoning in the second condition, it is always
It's easy to confirm in Postgres what the result value of these conditions are, as we have a boolean type. See dbfiddle.uk, where the first shows
As a result of the above, when you run your two queries, they become:
giving an empty result (correct, since the
and
giving one row (correct again).
WHERE NULL IN (SELECT 1 FROM dual WHERE 1 = 0);
WHERE NULL NOT IN (SELECT 1 FROM dual WHERE 1 = 0);since the subquery yields an empty table, we can write them in pseudocode:
WHERE NULL IN ();
WHERE NULL NOT IN ();So the first asks whether some (NULL) value is IN an empty table. The result of such condition is always
FALSE, independent on whether the value is null or not, since the table is empty.Applying the same reasoning in the second condition, it is always
TRUE, again independent of the value.It's easy to confirm in Postgres what the result value of these conditions are, as we have a boolean type. See dbfiddle.uk, where the first shows
f (FALSE) and the second shows t (TRUE).As a result of the above, when you run your two queries, they become:
SELECT 1
FROM dual
WHERE FALSE ;giving an empty result (correct, since the
WHERE condition is FALSE)and
SELECT 1
FROM dual
WHERE TRUE ;giving one row (correct again).
Code Snippets
WHERE NULL IN (SELECT 1 FROM dual WHERE 1 = 0);
WHERE NULL NOT IN (SELECT 1 FROM dual WHERE 1 = 0);WHERE NULL IN (<empty_table>);
WHERE NULL NOT IN (<empty_table>);SELECT 1
FROM dual
WHERE FALSE ;SELECT 1
FROM dual
WHERE TRUE ;Context
StackExchange Database Administrators Q#244148, answer score: 5
Revisions (0)
No revisions yet.