Filtering & predicates
Concept  ·  SQL & Querying

status <> 'refunded' silently excludes rows where status IS NULL — the predicate is UNKNOWN, not TRUE.

This is where_keeps_true meeting a business rule: 'everything except refunds' reads, to a human, as including the not-yet-statused — but the predicate never says so, and three-valued logic quietly sides with exclusion. Every <>, NOT IN-list, and NOT LIKE on a nullable column carries an implicit decision about NULLs the author probably didn't make.

See it break
rep
idstatus
1done
2refunded
3NULL
The trap
SELECT
  id
FROM
  rep
WHERE
  status <> 'refunded'
ORDER BY
  id;
The fix
SELECT
  id
FROM
  rep
WHERE
  status IS DISTINCT FROM 'refunded'
ORDER BY
  id;
The trap
1
The fix
1
3

'Everything except refunds' also dropped the unstatused repair — status <> 'refunded' is UNKNOWN where status is NULL, and WHERE keeps only TRUE; IS DISTINCT FROM (or OR status IS NULL) keeps the unknowns.

The rule

IS DISTINCT FROM; the OR-IS-NULL spelling; the decision, made visibly.

Shows up elsewhere
WHERE keeps only TRUEIS DISTINCT FROM (null-safe comparison)
Try one →Prove it in practice →