Chapter 06 · Functions, NULLs, and Conditional Logic
NULL Tests, COALESCE, NULLIF, and Safe Defaults
Preserve the distinction between unknown data and deliberate defaults while keeping reports and calculations usable.
Learning outcomes
NULL represents missing or inapplicable information. A safe SQL expression does not erase that meaning accidentally, but it can provide an explicit fallback where the result contract requires one.
Test missing values with IS NULL and IS NOT NULL.
Use COALESCE to choose the first available value.
Use NULLIF to convert sentinel or dangerous values into NULL.
Distinguish presentation defaults from stored facts and business defaults.
NULL propagates through many expressions
Missing information affects comparisons, arithmetic, concatenation, and many functions until an expression defines how to handle it.
SELECT 10 + NULL AS arithmetic_result, 'email: ' || NULL AS concatenation_result, LOWER(NULL) AS function_result, NULL = NULL AS equality_result, NULL IS NULL AS null_test_result;Ordinary equality does not answer whether a value is NULL. Use IS NULL or IS NOT NULL.
NULL tests preserve meaning
SELECT customer_id, full_name, emailFROM customerWHERE email IS NULLORDER BY customer_id;SELECT customer_id, full_name, emailFROM customerWHERE email = ''ORDER BY customer_id;The dataset intentionally contains both NULL and an empty string. They can represent different states and should not be merged without a business rule.
| Stored value | Possible meaning | Test |
|---|---|---|
| NULL | Unknown, unavailable, or not applicable | IS NULL |
| Empty string | Known to be empty | = '' |
| Whitespace | Entered but not meaningful | TRIM(x) = '' |
| Sentinel such as 0 or N/A | Legacy substitute for missingness | Convert deliberately after validating the domain |
COALESCE chooses the first non-NULL expression
SELECT customer_id, COALESCE(city, '[city unknown]') AS city_label, COALESCE(NULLIF(TRIM(email), ''), '[no email]') AS email_label, COALESCE(credit_limit, 0) AS displayed_credit_limitFROM customerORDER BY customer_id;COALESCE(a,b,c) checks arguments from left to right and returns the first non-NULL result. The chosen fallback becomes part of the output contract.
Data fallback
Prefer another stored field when it carries equivalent meaning.
Presentation fallback
Show a label such as “unknown” without changing stored data.
Calculation fallback
Use zero only when the business definition truly treats missing as zero.
Type fallback
Ensure candidate expressions have compatible, intentional result types.
Zero is not a universal safe default
SELECT customer_id, COALESCE(credit_limit, 0) AS credit_limitFROM customer;This may be correct for a display or a specific decision rule, but it also makes an unknown limit indistinguishable from a known limit of zero. A clearer report can expose both value and state.
SELECT customer_id, credit_limit, COALESCE(credit_limit, 0) AS calculation_limit, credit_limit IS NULL AS limit_was_missingFROM customerORDER BY customer_id;NULLIF returns NULL when two expressions are equal
SELECT customer_id, NULLIF(TRIM(email), '') AS normalized_emailFROM customerORDER BY customer_id;SELECT product_id, unit_price, stock_qty, unit_price / NULLIF(stock_qty, 0) AS price_per_stock_unitFROM productORDER BY product_id;If stock_qty is zero, NULLIF(stock_qty,0) returns NULL. The division then yields NULL instead of attempting a zero divisor. This is safer than fabricating a numeric answer.
COALESCE and NULLIF compose well
SELECT customer_id, COALESCE( LOWER(NULLIF(TRIM(email), '')), '[no usable email]' ) AS contact_emailFROM customerORDER BY customer_id;Evaluation proceeds inside out: trim, convert empty text to NULL, lowercase a usable value, then provide a display fallback.
NULL-aware calculations
SELECT s.sale_id, p.unit_price, s.quantity, s.discount_rate, ROUND(p.unit_price * s.quantity, 2) AS gross_amount, ROUND( p.unit_price * s.quantity * COALESCE(s.discount_rate, 0), 2 ) AS discount_amountFROM sale AS sJOIN product AS p ON p.product_id = s.product_idORDER BY s.sale_id;Here the reporting rule treats an absent discount rate as zero. That rule should be documented; another system might treat a missing rate as incomplete data requiring review.
Fallback types differ across engines
SQL engines determine a common result type for COALESCE and CASE according to their own type-resolution rules. Avoid mixing unrelated types merely because one branch is usually NULL.
SELECT COALESCE(credit_limit, CAST(0 AS REAL)) AS effective_limitFROM customer;-- This may coerce differently or fail across engines.SELECT COALESCE(credit_limit, 'unknown')FROM customer;Practice lab
- List customers with a missing city.
- Normalize NULL, empty, and whitespace-only emails into NULL.
- Display a fallback email label without modifying storage.
- Calculate sale discounts by treating a missing discount rate as zero.
- Calculate price per stock unit without dividing by zero.
SELECT customer_id, full_nameFROM customerWHERE city IS NULL;SELECT customer_id, NULLIF(TRIM(email), '') AS normalized_emailFROM customer;SELECT customer_id, COALESCE(NULLIF(TRIM(email), ''), '[no email]') AS email_labelFROM customer;SELECT sale_id, COALESCE(discount_rate, 0) AS effective_discount_rateFROM sale;SELECT product_id, unit_price / NULLIF(stock_qty, 0) AS price_per_stock_unitFROM product;Checkpoint
Choose the correct expression
- Which operator tests whether
cityis missing? - Which expression converts an empty string to NULL?
- When is
COALESCE(value,0)misleading? - Why can
NULLIF(divisor,0)be useful?
Review the answers
IS NULL; NULLIF(value,''); zero is misleading when unknown and known-zero are different states; NULLIF prevents a zero divisor from being treated as a valid denominator.
Common failures
Writing = NULL
The result is UNKNOWN rather than a successful null test.
Replacing every NULL with zero or empty text
This destroys distinctions that may matter to the business.
Using a sentinel instead of NULL
Values such as -1 or 'N/A' can collide with real domains and complicate constraints.
Mixing incompatible fallback types
Type resolution differs by engine and can produce errors or surprising coercion.
Hiding data-quality problems in presentation
A fallback label can make a report readable while the source still needs correction.
Summary and references
- Use
IS NULLandIS NOT NULLfor missingness. COALESCEreturns the first non-NULL candidate.NULLIFconverts a specific equal value into NULL.- Defaults must have an explicit business or presentation meaning.
- Expose missingness separately when a fallback could hide important state.