Re: RFC: A brief guide to nulls

From: Antti Haapala <antti(dot)haapala(at)iki(dot)fi>
To: dev(at)archonet(dot)com
Cc: pgsql-sql(at)postgresql(dot)org
Subject: Re: RFC: A brief guide to nulls
Date: 2003-01-15 19:51:16
Message-ID: Pine.GSO.4.44.0301152118010.15207-100000@paju.oulu.fi
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-sql


This should be added (From PostgreSQL integrated docs...):

SQL uses a three-valued Boolean logic where the null value represents
"unknown". Observe the following truth tables:

a | b | a AND b | a OR b
------+-------+---------+--------
TRUE | TRUE | TRUE | TRUE
TRUE | FALSE | FALSE | TRUE
TRUE | NULL | NULL | TRUE
FALSE | FALSE | FALSE | FALSE
FALSE | NULL | FALSE | NULL
NULL | NULL | NULL | NULL

So, if there's any trues in the chain of ORs, the whole expression will be
true, not null. This conforms to NULL representing unknown value. If you
have "true or unknown", of course whole result is true regardless of the
"unknown". Let's check this example:

> Subqueries and nulls
> ====================
> Since tests always fail when testing against nulls you can have unexpected
> results with sub-queries.
>
> Example: Assume we have a companies table and a diary table. Diary entries
> are usually related to a particular company but not always.
> SELECT co_name FROM companies WHERE co_id NOT IN (SELECT dy_company FROM
> diary);
> If any row in diary contains a null dy_company then you will get *no
> results*.
> We can expand the query like so:
> WHERE co_id NOT IN (SELECT dy_company FROM diary)
> WHERE co_id NOT IN (1, 2, null, 3...)
> WHERE NOT (co_id=1 OR co_id=2 OR co_id=null OR co_id=3...)
> WHERE NOT (... OR null OR ...)

> WHERE NOT (null)
(erm... actually not)

template1=# select 5 in (1, 2, 9, null);
?column?
----------

(1 row)

template1=# select 2 in (1, 2, 9, null);
?column?
----------
t
(1 row)

WHERE NOT (null/true) -> evaluates to
WHERE null/false

So the result was the same - but only for this example. Suppose you take
the NOT away:

template1=# select * from a where a.i in (1, 2, 9, null);
i
---
1
2
(2 rows)

I surely see two lines (not 0)... :)

And this could be added too, for clarification: "SELECT clause lists lines
for which the WHERE expression is certainly known to be true." ;)

--
Antti Haapala

In response to

Browse pgsql-sql by date

  From Date Subject
Next Message Tomasz Myrta 2003-01-15 19:59:43 Re: lost on self joins
Previous Message Tom Lane 2003-01-15 19:45:06 Re: sub-select with aggregate