Musisz rozróżnić dwie sytuacje: porównujesz jedną KOLUMNĘ z NULL lub porównujesz cały WIERSZ (NAGRYWANIE) z NULL.
Rozważ następujące zapytanie:
SELECT
id,
txt,
txt IS NULL AS txt_is_null,
NOT txt IS NULL AS not_txt_is_null,
txt IS NOT NULL AS txt_is_not_null
FROM
(VALUES
(1::integer, NULL::text)
)
AS x(id, txt) ;
Dostajesz to:
+----+-----+-------------+-----------------+-----------------+
| id | txt | txt_is_null | not_txt_is_null | txt_is_not_null |
+----+-----+-------------+-----------------+-----------------+
| 1 | | t | f | f |
+----+-----+-------------+-----------------+-----------------+
Myślę, że tego właśnie spodziewalibyśmy się. Sprawdzasz jedną KOLUMNĘ pod kątem NULL i otrzymujesz „txt IS NOT NULL” i „NOT txt IS NULL” są równoważne.
Jeśli jednak wykonasz inną kontrolę:
SELECT
id,
txt,
x IS NULL AS x_is_null,
NOT x IS NULL AS not_x_is_null,
x IS NOT NULL AS x_is_not_null
FROM
(VALUES
(1, NULL)
)
AS x(id, txt) ;
To dostajesz
+----+-----+-----------+---------------+---------------+
| id | txt | x_is_null | not_x_is_null | x_is_not_null |
+----+-----+-----------+---------------+---------------+
| 1 | | f | t | f |
+----+-----+-----------+---------------+---------------+
To może być zaskakujące. Jedna rzecz wygląda rozsądnie (x IS NULL), a (NOT x IS NULL) jest przeciwna do siebie. Inna sprawa (fakt, że ani „x IS NULL”, ani „x IS NOT NULL” nie są prawdziwe), wygląda dziwnie.
Jednak tak mówi dokumentacja PostgreSQL , która powinna się zdarzyć:
Jeśli wyrażenie ma wartość wiersza, wówczas IS NULL ma wartość true, gdy samo wyrażenie wiersza ma wartość NULL lub gdy wszystkie pola wiersza są puste, natomiast IS NOT NULL jest prawdziwe, gdy samo wyrażenie wiersza ma wartość inną niż null, a wszystkie pola wiersza są różna od zera. Z powodu tego zachowania IS NULL i IS NOT NULL nie zawsze zwracają odwrotne wyniki dla wyrażeń o wartościach wierszy; w szczególności wyrażenie o wartościach wierszy, które zawiera zarówno pola puste, jak i niepuste, zwróci wartość false dla obu testów. W niektórych przypadkach może być wskazane zapisanie wiersza IS DISTINCT FROM NULL lub row IS NOT DISTINCT FROM NULL, który po prostu sprawdzi, czy całkowita wartość wiersza jest null bez dodatkowych testów na polach wiersza.
Muszę wyznać, że nie sądzę, żebym kiedykolwiek używał porównania wartości równej zeru z wartością zerową, ale sądzę, że jeśli istnieje taka możliwość, może istnieć jakiś przypadek użycia. W każdym razie nie sądzę, żeby to było wspólne.