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.
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.
SELECT id,amount/NULLIF(amount,0) AS self_ratio
FROM sales WHERE amount IS NOT NULL ORDER BY id;id | self_ratio
101 | 1
102 | 1
103 | 1
105 | 1
106 | 1Every 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'tNULL, which makes fallback chains easy.NULLIF(a, b)returnsNULLwhenaequalsb, otherwisea;x / NULLIF(y, 0)avoids division-by-zero errors.COALESCE(SUM(x), 0)changes an empty total to 0, whileSUM(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,ISNULLandNVLare 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.
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.
SELECT id,COALESCE(city,'Unknown') AS city_label
FROM customers ORDER BY id;id | city_label
1 | Leeds
2 | Leeds
3 | Porto
4 | UnknownCommon 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.
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.
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
What does NULLIF(0,0) return?
- Zero because the first argument is zero
- True because the two values are equal
- NULL