Debe distinguir dos situaciones: compara una COLUMNA con NULL, o compara toda la FILA (REGISTRO) con NULL.
Considere la siguiente consulta:
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) ;
Obtienes esto:
+----+-----+-------------+-----------------+-----------------+
| id | txt | txt_is_null | not_txt_is_null | txt_is_not_null |
+----+-----+-------------+-----------------+-----------------+
| 1 | | t | f | f |
+----+-----+-------------+-----------------+-----------------+
Esto es, supongo, lo que tú y yo esperaríamos. Está comprobando una COLUMNA contra NULL, y obtiene "txt IS NOT NULL" y "NOT txt IS NULL" son equivalentes.
Sin embargo, si realiza una comprobación diferente:
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) ;
Entonces obtienes
+----+-----+-----------+---------------+---------------+
| id | txt | x_is_null | not_x_is_null | x_is_not_null |
+----+-----+-----------+---------------+---------------+
| 1 | | f | t | f |
+----+-----+-----------+---------------+---------------+
Esto puede ser sorprendente. Una cosa parece razonable (x IS NULL) y (NOT x IS NULL) son lo opuesto el uno del otro. La otra cosa (el hecho de que ni "x IS NULL" ni "x IS NOT NULL" son verdaderos) parece extraño.
Sin embargo, esto es lo que dice la documentación de PostgreSQL que debería suceder:
Si la expresión tiene un valor de fila, IS NULL es verdadero cuando la expresión de fila en sí es nula o cuando todos los campos de la fila son nulos, mientras que IS NOT NULL es verdadero cuando la expresión de fila en sí no es nula y todos los campos de la fila son nulos. no nulo Debido a este comportamiento, IS NULL y IS NOT NULL no siempre devuelven resultados inversos para expresiones con valores de fila; en particular, una expresión con valores de fila que contiene campos nulos y no nulos devolverá falso para ambas pruebas. En algunos casos, puede ser preferible escribir fila IS DISTINCT FROM NULL o row IS NOT DISTINCT FROM NULL, que simplemente comprobará si el valor general de la fila es nulo sin ninguna prueba adicional en los campos de la fila.
Debo confesar que no creo que alguna vez haya usado una comparación de valores de fila contra nulo, pero supongo que si existe la posibilidad, podría haber algún caso de uso para ello. No creo que sea común, de todos modos.