1.NULL as Unknown/Missing, Not an Ordinary Value
NULL is not zero, not an empty string, and not false — it is the absence of a known value. A numeric column that is NULL is not "0," a text column that is NULL is not "''," and a boolean column that is NULL is not "false." Each of those is a real, specific value; NULL is the claim that no value is recorded at all.
Key features
- NULL is not 0, not an empty string, and not false — those are all real, specific values
- A NULL in a numeric column does not participate in SUM/AVG as if it were zero — it is skipped entirely by aggregate functions
- Two NULLs are never considered equal to each other, because "unknown" is not "equal to another unknown"
- A column being NULL-able is a schema decision about whether "no value" is a legitimate state for that column
- PostgreSQL's aggregate functions (SUM, AVG, COUNT(col)) all ignore NULL rows rather than treating them as zero
NULL vs the nearest "empty-looking" real value, per type
- bonus = 0
- a fact: this employee's bonus is exactly zero
- participates normally in SUM/AVG
- counted by COUNT(bonus)
- bonus = NULL
- no fact recorded — bonus amount unknown/not applicable
- skipped entirely by SUM/AVG, not treated as 0
- NOT counted by COUNT(bonus)
Command
SELECT count(*) AS all_rows, count(bonus) AS rows_with_a_bonus, avg(bonus) AS avg_of_known_bonuses
FROM employees;NULL means no value was recorded — not zero, not empty string, not false. Aggregate functions like SUM/AVG/COUNT(col) skip NULL rows entirely rather than treating them as zero.