SQL IFNULL, COALESCE and NULLIF
NULL breaks arithmetic, string concatenation and averages (NULL Values). Three small functions fix that: COALESCE and IFNULL replace NULL with a value you choose, and NULLIF does the opposite, turning a value into NULL, which is the standard trick to avoid division by zero.
- Replace NULL with a default using
COALESCEandIFNULL - Pick the first non-NULL value from several columns
- Avoid division by zero with
NULLIF - Know the difference between
COALESCEandIFNULL
Sample data
| emp_id | first_name | dept_id | manager_id | salary | commission |
|---|---|---|---|---|---|
| 100 | Meera | NULL | NULL | 250000 | NULL |
| 101 | Asha | 1 | 100 | 125000 | NULL |
| 102 | Rahul | 1 | 101 | 98000 | NULL |
| 103 | Priya | 1 | 101 | 72000 | NULL |
| 104 | Karan | 1 | 102 | 72000 | NULL |
| 105 | Vikram | 2 | 100 | 105000 | 12000 |
| 106 | Neha | 2 | 105 | 54000 | 6000 |
| 107 | Arjun | 2 | 105 | 48000 | 4500 |
| 108 | Kavya | 3 | 100 | 88000 | NULL |
| 109 | Rohan | 3 | 108 | 45000 | NULL |
| 110 | Sneha | 4 | 100 | 78000 | NULL |
| 111 | Amit | 1 | 101 | 25000 | NULL |
COALESCE
COALESCE(a, b, c, ...) returns the first argument that is not NULL:
SELECT first_name, commission, COALESCE(commission, 0) AS commission_or_zero, salary + COALESCE(commission, 0) AS total_payFROM employeesWHERE dept_id IN (2, 3);| first_name | commission | commission_or_zero | total_pay |
|---|---|---|---|
| Vikram | 12000 | 12000 | 117000 |
| Neha | 6000 | 6000 | 60000 |
| Arjun | 4500 | 4500 | 52500 |
| Kavya | NULL | 0 | 88000 |
| Rohan | NULL | 0 | 45000 |
- For sales staff
commissionhas a value, soCOALESCEreturns it. - For Marketing it is NULL, so
COALESCEmoves on to the next argument: 0. - The total pay is now a real number for everyone.
With several arguments it picks the first available value. Show the best contact for each customer: email, otherwise city:
SELECT customer_name, email, city, COALESCE(email, CONCAT('no email - ', city)) AS contactFROM customersWHERE customer_id IN (3, 4, 5);| customer_name | city | contact | |
|---|---|---|---|
| Fatima Khan | fatima@example.com | Hyderabad | fatima@example.com |
| David Fernandes | NULL | Goa | no email – Goa |
| Ishita Bose | ishita@example.com | Kolkata | ishita@example.com |
IFNULL
IFNULL(a, b) is MySQL’s two-argument version: a if it is not NULL, otherwise b.
SELECT first_name, IFNULL(dept_id, 'none') AS dept, IFNULL(manager_id, 'top') AS reports_toFROM employeesWHERE emp_id IN (100, 101, 102);| first_name | dept | reports_to |
|---|---|---|
| Meera | none | top |
| Asha | 1 | 100 |
| Rahul | 1 | 101 |
- Meera (100) has no department and no manager, so both columns show the replacement text.
- Asha and Rahul have values, which are shown unchanged.
COALESCE | IFNULL | |
|---|---|---|
| Arguments | 2 or more | exactly 2 |
| Standard SQL | yes, works everywhere | MySQL (SQL Server: ISNULL, Oracle: NVL) |
Prefer COALESCE unless you are sure the query will only ever run on MySQL.
NULLIF: avoid division by zero
NULLIF(a, b) returns NULL when a = b, otherwise a. Divide by NULLIF(x, 0) and a zero divisor gives NULL instead of a problem:
SELECT product_name, price, stock, price / NULLIF(stock, 0) AS price_per_unit_in_stockFROM productsWHERE category = 'Electronics';| product_name | price | stock | price_per_unit_in_stock |
|---|---|---|---|
| Wireless Mouse | 799 | 120 | 6.6583 |
| Mechanical Keyboard | 3499 | 45 | 77.7556 |
| USB-C Hub | 1999 | 0 | NULL |
- For products with stock,
NULLIF(stock, 0)returns the stock and the division works. - The USB-C Hub has
stock = 0, soNULLIFreturns NULL, and dividing by NULL gives NULL.
MySQL returns NULL (with a warning) for division by zero in a plain SELECT, but in strict mode an INSERT or UPDATE that divides by zero fails. Other databases such as PostgreSQL and SQL Server raise an error even in SELECT. NULLIF makes the intent explicit everywhere.
NULLIF also turns “empty” placeholder values into real NULLs, so they are skipped by aggregates:
CREATE TABLE survey (respondent INT, score INT);INSERT INTO survey VALUES (1, 8), (2, 0), (3, 6), (4, 0);SELECT AVG(score) AS avg_with_zeros, AVG(NULLIF(score, 0)) AS avg_answered_onlyFROM survey;| avg_with_zeros | avg_answered_only |
|---|---|
| 3.5000 | 7.0000 |
- In this survey, 0 means “did not answer”.
AVG(score)counts the zeros: (8 + 0 + 6 + 0) / 4 = 3.5.NULLIF(score, 0)turns them into NULL, soAVGuses only the real answers: (8 + 6) / 2 = 7.
IF()
MySQL’s IF(condition, then, else) is handy for one quick test:
SELECT first_name, IF(commission IS NULL, 'Salary only', 'Salary + commission') AS pay_typeFROM employeesWHERE dept_id = 2 OR emp_id = 101;| first_name | pay_type |
|---|---|
| Asha | Salary only |
| Vikram | Salary + commission |
| Neha | Salary + commission |
| Arjun | Salary + commission |
For more than one condition use CASE.
Exercise: Readable departments
Show each employee’s first_name and the department id, but print 0 instead of NULL. Order by that column.
| first_name | dept |
|---|---|
| Meera | 0 |
| Amit | 1 |
| Asha | 1 |
| Karan | 1 |
| Priya | 1 |
| Rahul | 1 |
| Arjun | 2 |
| Neha | 2 |
| Vikram | 2 |
| Kavya | 3 |
| Rohan | 3 |
| Sneha | 4 |
Hint 1
COALESCE(dept_id, 0).
SELECT first_name, COALESCE(dept_id, 0) AS deptFROM employeesORDER BY dept, first_name;| first_name | dept |
|---|---|
| Meera | 0 |
| Amit | 1 |
| Asha | 1 |
| Karan | 1 |
| Priya | 1 |
| Rahul | 1 |
| Arjun | 2 |
| Neha | 2 |
| Vikram | 2 |
| Kavya | 3 |
| Rohan | 3 |
| Sneha | 4 |
Quick quiz
1. What does COALESCE(NULL, NULL, 5, 7) return?
COALESCE returns the first non-NULL argument.
2. What does NULLIF(10, 10) return?
NULLIF returns NULL when both values are equal.
3. Which function is standard SQL and works in every database?
COALESCE is part of the SQL standard.
COALESCE and IFNULL FAQ
What is the difference between COALESCE and IFNULL?
IFNULL takes exactly two arguments and is MySQL-specific. COALESCE takes any number of arguments, returns the first non-NULL one, and is standard SQL.
How do I replace NULL with 0 in SQL?
Use COALESCE(column, 0), or IFNULL(column, 0) in MySQL.
How do I avoid a divide-by-zero error in SQL?
Divide by NULLIF(divisor, 0). When the divisor is 0 the result becomes NULL instead of an error; wrap it in COALESCE(..., 0) if you prefer 0.
What does NULLIF do?
NULLIF(a, b) returns NULL if a equals b, otherwise it returns a.