COALESCE and NULLIF
Objectives
By the end of this lesson, you should be able to:
- Replace a
NULLvalue with a fallback usingCOALESCE() - Turn a specific value into
NULLusingNULLIF() - Use
NULLIF()to guard against division by zero
💡 Why this matters: A
NULLdepartment showing up as a blank cell in a report is confusing,COALESCE()fills it with something readable. Occasionally the opposite is needed too, treating a specific ordinary value (like0) as if it were missing, which is whatNULLIF()does.
⚠️ A note on verification: every statement and result in this lesson was run against a real, live PostgreSQL 18 database, using the
employeestable from earlier lessons.
COALESCE()
SELECT first_name, COALESCE(department, 'Unassigned') AS department
FROM employees
WHERE first_name = 'Devon';
first_name | department
------------+-------------
Devon | Unassigned
COALESCE(value, fallback) returns value if it isn’t NULL, otherwise it returns fallback. Devon’s department is NULL (no department assigned), so COALESCE substitutes 'Unassigned' instead. COALESCE() actually accepts any number of arguments, not just two, returning the first one that isn’t NULL, useful for a chain of fallbacks (COALESCE(preferred_name, first_name, 'Unknown')).
NULLIF()
SELECT NULLIF(10, 10) AS same, NULLIF(10, 5) AS different;
same | different
------+------------
| 10
NULLIF(a, b) returns NULL if a equals b, otherwise it returns a unchanged. NULLIF(10, 10) becomes NULL since both arguments match, NULLIF(10, 5) stays 10 since they don’t. This is, in a sense, the reverse of COALESCE, instead of replacing NULL with a real value, it replaces a specific real value with NULL.
NULLIF as a Division-by-Zero Guard
SELECT 10 / NULLIF(0, 0) AS safe_div;
safe_div
----------
Dividing by zero normally raises a hard error in PostgreSQL. NULLIF(0, 0) turns the divisor into NULL whenever it would have been 0, and dividing by NULL returns NULL (Module 6) instead of erroring. 10 / NULLIF(some_count, 0) is a common real pattern, computing a rate or average that would otherwise crash on an empty group.
Try It
- Write a query showing every employee’s
department, replacingNULLwith'No Department', usingCOALESCE. - Write a query computing
salary / NULLIF(0, 0)and confirm it returnsNULLinstead of an error. - Write a query using
COALESCEwith three fallback values (a literalNULL, then another literalNULL, then a real value), and confirm it returns the first non-NULLone. - Explain, in your own words, a real reporting scenario where
NULLIFguarding a division makes more sense than just checkingWHERE count > 0beforehand.
Recap
COALESCE(value, fallback, ...)returns the first non-NULLargument, commonly used to display a default instead of a blankNULL.NULLIF(a, b)returnsNULLifaequalsb, otherwise returnsa, the reverse operation fromCOALESCE.NULLIFcombined with division is a standard guard against dividing by zero, since PostgreSQL returnsNULL(not an error) forvalue / NULL.
Next lesson: EXISTS, ANY, and ALL, existence and comparison checks against a subquery.