Subject RE: [firebird-support] Re: Latest entries on either Date or Batch No. field
Author Svein Erling Tysvær
>There's a semantic difference between NOT IN and the equivalent NOT EXISTS having to do
>with NULL values and empty result sets. I've understood it from time to time, but this
>is not one of those times. So it's not possible to fold all IN subqueries into EXISTS
>subqueries. Worse, the NOT IN defies index optimization.

Below is one example (assuming rdb$description is null).

This doesn't return anything since it is unknown whether NULL is in [NULL] or not:
select r1.*
from rdb$database r1
where r1.rdb$description not in (select r2.rdb$description
from rdb$database r2)

This returns one row since the equivalence test doesn't return anything and, hence, NOT EXISTS yields true:
select r1.*
from rdb$database r1
where not exists (select * from rdb$database r2
where r1.rdb$description = r2.rdb$description)

The top select could be translated:
select r1.*
from rdb$database r1
where not exists (select * from rdb$database r2
where r1.rdb$description = r2.rdb$description
and r1.rdb$description is not NULL
and r2.rdb$description is not NULL)

but I don't think all cases are that easily translated.

And, of course, I agree that NOT IN (SELECT) often is a lot worse than IN(SELECT), although I do think the WHERE clause matters (if the Firebird crew has managed to translate all cases of IN into EXISTS under the hood, then I agree it doesn't matter).

Set