SQL COALESCE and NULLIF: Practical NULL Handling

COALESCE returns the first non-NULL expression, while NULLIF returns NULL when its two expressions compare equal.

Lesson 46 of 102Intermediate10 min read

COALESCE returns the first non-NULL expression, while NULLIF returns NULL when its two expressions compare equal.

Missing data sometimes needs a display fallback, and invalid ratios sometimes need a missing result. COALESCE and NULLIF solve those two tasks, but their placement can change the meaning of a calculation. Decide the fallback policy before writing the expression.

This reference adds detail to the main course. You can read it independently: the small database below supplies every table and row used in the examples. Start with the question each query answers, then compare the returned values with the data rather than memorising a line of syntax.

Set up the practice database

Run this setup once in a new practice database, before the examples. It uses four customers and six sales. Ana has two sales, Ben has one, Cara has two, and Dev has none.

Sale 106 has no customer link; sale 104 has an unknown amount. These deliberate test cases expose missing information and unmatched relationships.

SQL
CREATE TABLE customers (
  id INTEGER PRIMARY KEY,
  name VARCHAR(40) NOT NULL,
  city VARCHAR(40),
  manager_id INTEGER
);
CREATE TABLE sales (
  id INTEGER PRIMARY KEY,
  customer_id INTEGER,
  amount DECIMAL(10,2),
  status VARCHAR(20) NOT NULL,
  created_on DATE NOT NULL
);
INSERT INTO customers (id,name,city,manager_id) VALUES
  (1,'Ana','Leeds',NULL),(2,'Ben','Leeds',1),
  (3,'Cara','Porto',1),(4,'Dev',NULL,2);
INSERT INTO sales (id,customer_id,amount,status,created_on) VALUES
  (101,1,10,'paid','2026-01-01'),
  (102,1,30,'pending','2026-01-02'),
  (103,2,20,'paid','2026-01-02'),
  (104,3,NULL,'pending','2026-02-01'),
  (105,3,20,'paid','2026-02-02'),
  (106,NULL,5,'paid','2026-02-03');

An amount of zero would be a known value. The NULL amount here means the value is unknown. A customer with no matching sale differs from a sale whose customer_id is NULL.

The primary keys identify individual records even when amounts or cities repeat. Dates use year-month-day format. The examples specify sorting whenever order matters; insertion order alone does not guarantee display order.

How COALESCE and NULLIF works

COALESCE(city,'Unknown') returns the saved city when present and the chosen label when absent. Several arguments are allowed, so COALESCE(primary_phone,backup_phone,'No phone') expresses a fallback chain. It does not change the stored columns. A known empty string remains the selected value because empty text is not NULL in these engines. If empty text should count as missing, convert it deliberately with NULLIF before applying the fallback.

NULLIF(x,y) acts like a comparison-based missing-value expression. If x equals y, the result is NULL; otherwise it returns x. NULLIF(denominator,0) is a common way to avoid a zero denominator. NULLIF(TRIM(label),'') turns a whitespace-trimmed empty label into missing text. That is a data policy, so ensure a genuine empty label is actually supposed to be treated as absent. The two arguments must have types the database can compare sensibly.

COALESCE inside or outside an aggregate

Placement around an aggregate matters. COALESCE(SUM(amount),0) converts an unavailable sum to zero after normal aggregate processing. SUM(COALESCE(amount,0)) changes each missing input amount to zero before addition. Their outputs can coincide in a simple total while expressing different assumptions and behaving differently over empty input. For AVG, the distinction is directly visible: replacing missing input with zero increases the denominator, while replacing only a missing final average does not.

Type resolution considers the expressions in the function, not just the value chosen on one sample row. Mixing a numeric amount with a text fallback such as 'Unknown' can fail in strongly typed engines or trigger an unwanted conversion. Keep numeric computations numeric, and create display text separately. If a ratio becomes NULL because its denominator is zero, immediately converting that to zero can hide the reason it is undefined. A clear unavailable label may be more truthful than a numeric default.

MySQL, PostgreSQL, SQL Server and SQLite

COALESCE and NULLIF are supported by all four systems. SQL Server ISNULL, MySQL IFNULL and SQLite ifnull are related dialect functions, but their type rules or argument limits differ. Prefer the standard-style functions when sharing queries, and check return-type behaviour when arguments have different numeric or text types.

Check the engine-specific syntax and version requirements in PostgreSQL conditional expressions.

Practice task and worked solution

Show the known amount per sale and a safe ratio amount divided by amount. Exclude missing amounts for this exercise and use NULLIF to handle any future zero amount.

Try the task before reading its worked solution. The supplied rows make the expected answer checkable by hand.

SQL
SELECT id,amount/NULLIF(amount,0) AS self_ratio
FROM sales WHERE amount IS NOT NULL ORDER BY id;
Output
id | self_ratio
101 | 1
102 | 1
103 | 1
105 | 1
106 | 1

Every supplied known amount is nonzero, so division by itself yields one. If a zero were added, NULLIF would convert its denominator to NULL and the ratio would be NULL. It would not label the undefined zero-divided-by-zero case as a known one.

Evaluate COALESCE('','Unknown') and COALESCE(NULL,'Unknown') to see that empty text remains present. Then test COALESCE(NULLIF(TRIM(' '),''),'Unknown') to observe an explicit whitespace policy. Compare AVG(COALESCE(amount,0)) with COALESCE(AVG(amount),0) on the sample sales: their different denominators make the placement of the fallback visible.

SQL COALESCE and NULLIF: Practical NULL Handling Syntax

COALESCE and NULLIF

SELECT id,COALESCE(city,'Unknown') AS city_label
FROM customers ORDER BY id;

SQL COALESCE and NULLIF: Practical NULL Handling Summary

  • COALESCE(a, b, ...) returns the first argument that isn't NULL, which makes fallback chains easy.
  • NULLIF(a, b) returns NULL when a equals b, otherwise a; x / NULLIF(y, 0) avoids division-by-zero errors.
  • COALESCE(SUM(x), 0) changes an empty total to 0, while SUM(COALESCE(x, 0)) treats each missing input as 0.
  • Keep result types consistent: don't mix a numeric column with a text label in one COALESCE.
  • IFNULL, ISNULL and NVL are dialect versions with different argument limits and type rules.

SQL COALESCE and NULLIF: Practical NULL Handling Examples

Each example shows the code, the output it produces and what each part does.

Example 1

A display label for a missing city

The first argument is present for three customers. Dev’s missing city falls through to the second argument, producing a display label. The query returns text throughout and leaves the saved NULL intact.

SQL
SELECT id,COALESCE(city,'Unknown') AS city_label
FROM customers ORDER BY id;
Output
id | city_label
1 | Leeds
2 | Leeds
3 | Porto
4 | Unknown

Common SQL COALESCE and NULLIF: Practical NULL Handling Mistakes

Mixing numbers and labels in COALESCE

COALESCE(amount,'Unknown') mixes a numeric measure with a text label and may fail through conversion or produce inconsistent types. Keep the amount column numeric and let the interface show a label for NULL. Using COALESCE(...,0) around every ratio can also disguise undefined results as real zero measurements.

SQL COALESCE and NULLIF: Practical NULL Handling in Real Projects

Unknown labels and undefined ratios in exports

A customer export can show an explicit unknown city label while preserving the source marker for data-quality work. A financial ratio can use NULLIF on its denominator so an empty or zero baseline remains visibly unavailable. Those are different fallback policies and should be documented separately.

Document each fallback by meaning: Unknown is a display label, zero may be a real no-activity measure, and NULL may indicate an undefined ratio. Do not force those states into one numeric default. If an import turns empty text into missing input, retain the raw field so the transformation remains distinguishable from originally absent data.

SQL COALESCE and NULLIF: Practical NULL Handling FAQ

Does COALESCE replace empty strings?

No. An empty string is a present value, so COALESCE('', 'Unknown') returns ''. Use an explicit empty-string rule if needed, for example COALESCE(NULLIF(TRIM(city), ''), 'Unknown'), which treats blank and missing cities the same way.

Does NULLIF return a boolean?

No. It returns NULL when its two arguments are equal, and its first expression otherwise. NULLIF(quantity, 0) therefore returns the quantity, or NULL when the quantity is 0, which is why it fits naturally into a denominator.

Should all missing measures become zero?

Only if zero accurately expresses the business meaning. An unknown measurement or an undefined ratio often needs to stay missing, so readers can see that the data isn't available rather than seeing a misleading 0.

What is the difference between COALESCE and ISNULL in SQL Server?

COALESCE is standard, accepts any number of arguments and takes its result type from the highest-precedence argument. SQL Server's ISNULL takes exactly two and uses the first argument's type, so a longer fallback string can be cut short. Prefer COALESCE unless you need ISNULL's specific behaviour.

Can COALESCE choose between several columns?

Yes. COALESCE(mobile_phone, home_phone, work_phone) returns the first phone number that is present for each row, and you can end the list with a fixed fallback such as 'No phone'. The arguments are checked from left to right.

SQL COALESCE and NULLIF: Practical NULL Handling Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Multiple choicemedium

What city_label does COALESCE(city,'Unknown') return for Dev?

SQL COALESCE and NULLIF: Practical NULL Handling Quiz

2 questions to check what you learned.

  1. What does COALESCE(city,'Unknown') choose first?

    • The last argument regardless of which values are present
    • The first non-NULL argument
    • The first argument even when it is NULL
  2. What does NULLIF(0,0) return?

    • Zero because the first argument is zero
    • True because the two values are equal
    • NULL