Re: I don't understand something... - Mailing list pgsql-general

From Alban Hertroys
Subject Re: I don't understand something...
Date
Msg-id CAF-3MvPgzbF8fvDsCqDocs1u+Q-6RVXMHt05sw0cwmt9fUFxqA@mail.gmail.com
Whole thread Raw
In response to I don't understand something...  (Alexander Pyhalov <alp@rsu.ru>)
List pgsql-general
On 3 October 2011 08:33, Alexander Pyhalov <alp@rsu.ru> wrote:
> Now we want to select count of all employees who doesn't have any
> subordinates (query 1):
>  SELECT count(employee_id) from employees o where not exists  (select 1 from
> employees  where manager_id=o.employee_id);
>  count
> -------
>    89
> (1 row)
>
> We can select count of all managers (query 2):
> SELECT count(employee_id) from employees where employee_id  in (select
> manager_id from employees);
>  count
> -------
>    18
> (1 row)
>
> But if we reformulate the first query in the same way, answer is different
> (query 3):
> SELECT count(employee_id) from employees where employee_id not in (select
> manager_id from employees) (query 3);
>  count
> -------
>     0
> (1 row)
>
> I don't understand why queries 1 and 3 give different results. They seems to
> be the same... Could someone explain the difference?

That's because NOT IN returns NULL if there are any NULLs in the list.
As the WHERE-clause requires something to evaluate to either true or
false (NULL won't do), you (correctly) get false if someone is a
manager, but also if _anyone_ is NOT a manager.

That's an artefact of how 3-valued logic is implemented in the SQL standard.

--
If you can't see the forest for the trees,
Cut the trees and you'll see there is no forest.

pgsql-general by date:

Previous
From: Joe Abbate
Date:
Subject: Re: PL/Python
Next
From: Venkat Balaji
Date:
Subject: Re: : PostgreSQL Online Backup