NULL & three-valued logic
Concept  ·  SQL & Querying

WHERE drops UNKNOWN and FALSE alike — the root cause behind half the P01/P04 traps.

WHERE keeps a row only when the predicate is TRUE; it drops FALSE and UNKNOWN alike. A comparison against NULL is UNKNOWN, so any plain <> / = filter silently discards the NULL rows — the root cause behind many filtering and aggregation surprises.

See it break
tickets
idpriority
1high
2NULL
3low
The trap
SELECT
  id
FROM
  tickets
WHERE
  priority <> 'high'
ORDER BY
  id;
The fix
SELECT
  id
FROM
  tickets
WHERE
  priority IS DISTINCT FROM 'high'
ORDER BY
  id;
The trap
3
The fix
2
3

The 'not high priority' queue loses every ticket with a blank priority — WHERE drops the UNKNOWN rows along with the FALSE ones.

The rule

When NULL rows should survive a not-equal filter, use IS DISTINCT FROM, or add OR col IS NULL explicitly.

Shows up elsewhere
NULL = NULL is not TRUE
Try one →Prove it in practice →