Re: Weird NOT IN effect with NULL values - Mailing list pgsql-sql

From Tom Lane
Subject Re: Weird NOT IN effect with NULL values
Date
Msg-id 21957.983472966@sss.pgh.pa.us
Whole thread Raw
In response to Weird NOT IN effect with NULL values  (Frank Joerdens <frank@joerdens.de>)
List pgsql-sql
Frank Joerdens <frank@joerdens.de> writes:
> When doing a subselect with NOT IN, as in
> SELECT name
> FROM customer
> WHERE customer_id NOT IN (
> SELECT customer_id
> FROM salesorder
> );
> I get no rows if the result column returned by the subselect
> contains NULL values. It works as expected if I remove the NULL values
> from the result set. Is this behaviour correct and if so, why?

This is correct because of SQL's 3-valued boolean logic.  SQL92 defines
"A NOT IN B" as equivalent to "NOT (A = SOME B)", and the latter has
the rules
           c) If the implied <comparison predicate> is true for at least             one row RT in T, then "R <comp op>
<some>T" is true.
 
           d) If T is empty or if the implied <comparison predicate> is             false for every row RT in T, then
"R<comp op> <some> T" is             false.
 
           e) If "R <comp op> <quantifier> T" is neither true nor false,             then it is unknown.

Now the implied comparison will generate TRUE for the subselect rows
that contain a matching customer_id, FALSE for the rows that contain
non-matching (but not null) customer_id, and UNKNOWN (null) for the
rows that contain nulls.  So if you have nulls then case (d) never
holds: the result of A = SOME B is either true or unknown.  And so
the result of NOT IN is either false or unknown, and either way the
outer WHERE fails.

This can be justified intuitively if you consider that null means
"don't know": you can say for sure that the target customer_id IS in
the subselect if you find it there, but you can't say for sure that it
IS NOT there, because you don't know all the subselect result elements.

Bottom line: you probably want to suppress nulls in the subselect...
        regards, tom lane


pgsql-sql by date:

Previous
From: Ken Kline
Date:
Subject: Re: Weird NOT IN effect with NULL values
Next
From: Bruce Momjian
Date:
Subject: Re: Weird NOT IN effect with NULL values