Contents

Backend Development › Relational Databases & SQL

NULL in SQL

Three-valued logic, and why NULL = NULL isn't true.

Also known as: NULL, IS NULL, three-valued logic, NULL handling, NULL comparison

In SQL, NULL means “unknown or missing”, not zero and not an empty string. Because it’s unknown, comparing anything to it gives neither true nor false, but unknown. That’s called three-valued logic, and it causes many surprises.

SELECT NULL = NULL;      -- NULL (unknown), not true
SELECT NULL = 5;         -- NULL
SELECT NULL <> 5;        -- NULL
SELECT 1 + NULL;         -- NULL

WHERE keeps only rows where the condition is true. Unknown is dropped.

Testing for NULL

WHERE phone IS NULL
WHERE phone IS NOT NULL
-- WHERE phone = NULL       never matches anything

Traps

Rows with NULL vanish from comparisons.

SELECT * FROM users WHERE status <> 'banned';
-- users whose status is NULL are NOT returned: NULL <> 'banned' is unknown
-- fix: WHERE status <> 'banned' OR status IS NULL

NOT IN with a NULL in the list returns nothing.

SELECT * FROM a WHERE id NOT IN (SELECT a_id FROM b);   -- if any b.a_id is NULL: zero rows!
-- safer: WHERE NOT EXISTS (SELECT 1 FROM b WHERE b.a_id = a.id)

Aggregates skip NULLs. COUNT(col), SUM, AVG, MIN and MAX ignore NULL values. COUNT(*) counts rows. AVG divides by the number of non-null values, not the number of rows (GROUP BY).

Joins: a NULL never matches in ON a.x = b.x. Outer joins produce NULLs for the missing side (join types).

Uniqueness: whether a unique constraint allows several NULLs depends on the database.

Handling it

COALESCE(phone, 'unknown')             -- first non-null value
NULLIF(x, 0)                           -- NULL if x = 0 (avoids divide by zero)
CASE WHEN phone IS NULL THEN ... END   -- see CASE expressions

See COALESCE and NULLIF.

Sort order of NULLs (first or last) differs between databases, so say NULLS FIRST or NULLS LAST where supported if it matters. Mark columns NOT NULL when a value is always required. It removes a whole class of bugs (constraints). The idea is related to null in programming languages, but the rules are different.