Re: Weird NOT IN effect with NULL values

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Frank Joerdens <frank(at)joerdens(dot)de>
Cc: pgsql-sql(at)postgresql(dot)org
Subject: Re: Weird NOT IN effect with NULL values
Date: 2001-03-01 18:56:06
Message-ID: 21957.983472966@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-sql

Frank Joerdens <frank(at)joerdens(dot)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

In response to

Browse pgsql-sql by date

  From Date Subject
Next Message Peter Eisentraut 2001-03-01 18:59:54 Re: Weird NOT IN effect with NULL values
Previous Message Bruce Momjian 2001-03-01 18:42:10 Re: Weird NOT IN effect with NULL values