Check the IN
documentation, in particular:
Any null values ββreturned by a subquery or expression that are compared to test_expression using IN or NOT IN return UNKNOWN. Using null values ββwith IN or NOT IN may produce unexpected results.
You have not shown them, but I am sure that you have at least one NULL
value hidden in your data.
You can exclude NULL
(s), and then NOT IN
will work as you expected:
SELECT column1 FROM Table1 WHERE column1 NOT IN (SELECT t2.column1 FROM Table2 t2 WHERE t2.column1 IS NOT NULL)
IN
and NOT IN
are opposites within the wave side, but you have to consider SQL three-valued logic . Imagine we wrote IN
using the form of expression
a IN (1,2,NULL)
Which is handled in the same way as:
a = 1 OR a = 2 or a = NULL
For any row, where a = 1, we have:
TRUE OR TRUE OR UNKNOWN
which is equal to TRUE
. And for any row, where a = 3, let's say we have:
FALSE OR FALSE OR UNKNOWN
which is equal to UNKNOWN
Now consider NOT IN
as follows:
a NOT IN (1,2,NULL)
Which is handled in the same way as:
a != 1 AND a != 2 AND a != NULL
For any row, where a = 1, we have:
FALSE AND TRUE AND UNKNOWN
This is FALSE
. And for a = 3 we have:
TRUE AND TRUE AND UNKNOWN
This is UNKNOWN
. Having NULL
means that there is no way to get this AND
chain to get TRUE
.