SQL Tutorial › Functions & Grouping › IFNULL & COALESCE

SQL IFNULL, COALESCE and NULLIF

IntermediateLesson 29 of 698 min read6 queries run on MySQL 8.4

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.

Advertisement
In this lesson
  • Replace NULL with a default using COALESCE and IFNULL
  • Pick the first non-NULL value from several columns
  • Avoid division by zero with NULLIF
  • Know the difference between COALESCE and IFNULL

Sample data

employees · 12 rows (some columns)
emp_idfirst_namedept_idmanager_idsalarycommission
100MeeraNULLNULL250000NULL
101Asha1100125000NULL
102Rahul110198000NULL
103Priya110172000NULL
104Karan110272000NULL
105Vikram210010500012000
106Neha2105540006000
107Arjun2105480004500
108Kavya310088000NULL
109Rohan310845000NULL
110Sneha410078000NULL
111Amit110125000NULL

COALESCE

COALESCE(a, b, c, ...) returns the first argument that is not NULL:

SQL
SELECT first_name, commission,       COALESCE(commission, 0)          AS commission_or_zero,       salary + COALESCE(commission, 0) AS total_payFROM employeesWHERE dept_id IN (2, 3);
ResultMySQL 8.4
first_namecommissioncommission_or_zerototal_pay
Vikram1200012000117000
Neha6000600060000
Arjun4500450052500
KavyaNULL088000
RohanNULL045000
5 rows in set
How this query works, step by step
  1. For sales staff commission has a value, so COALESCE returns it.
  2. For Marketing it is NULL, so COALESCE moves on to the next argument: 0.
  3. 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:

SQL
SELECT customer_name, email, city,       COALESCE(email, CONCAT('no email - ', city)) AS contactFROM customersWHERE customer_id IN (3, 4, 5);
ResultMySQL 8.4
customer_nameemailcitycontact
Fatima Khanfatima@example.comHyderabadfatima@example.com
David FernandesNULLGoano email – Goa
Ishita Boseishita@example.comKolkataishita@example.com
3 rows in set

IFNULL

IFNULL(a, b) is MySQL’s two-argument version: a if it is not NULL, otherwise b.

SQL
SELECT first_name,       IFNULL(dept_id, 'none')    AS dept,       IFNULL(manager_id, 'top')  AS reports_toFROM employeesWHERE emp_id IN (100, 101, 102);
ResultMySQL 8.4
first_namedeptreports_to
Meeranonetop
Asha1100
Rahul1101
3 rows in set
How this query works, step by step
  1. Meera (100) has no department and no manager, so both columns show the replacement text.
  2. Asha and Rahul have values, which are shown unchanged.
COALESCEIFNULL
Arguments2 or moreexactly 2
Standard SQLyes, works everywhereMySQL (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:

MySQL
SELECT product_name, price, stock,       price / NULLIF(stock, 0) AS price_per_unit_in_stockFROM productsWHERE category = 'Electronics';
ResultMySQL 8.4
product_namepricestockprice_per_unit_in_stock
Wireless Mouse7991206.6583
Mechanical Keyboard34994577.7556
USB-C Hub19990NULL
3 rows in set
How this query works, step by step
  1. For products with stock, NULLIF(stock, 0) returns the stock and the division works.
  2. The USB-C Hub has stock = 0, so NULLIF returns NULL, and dividing by NULL gives NULL.
Note

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:

MySQL
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;
ResultMySQL 8.4
mysql> CREATE TABLE survey (respondent INT, score INT)
Query OK, 0 rows affected
mysql> INSERT INTO survey VALUES (1, 8), (2, 0), (3, 6), (4, 0)
Query OK, 4 rows affected
mysql> SELECT AVG(score) AS avg_with_zeros, AVG(NULLIF(score, 0)) AS avg_answ…
avg_with_zerosavg_answered_only
3.50007.0000
1 row in set
How this query works, step by step
  1. In this survey, 0 means “did not answer”.
  2. AVG(score) counts the zeros: (8 + 0 + 6 + 0) / 4 = 3.5.
  3. NULLIF(score, 0) turns them into NULL, so AVG uses only the real answers: (8 + 6) / 2 = 7.

IF()

MySQL’s IF(condition, then, else) is handy for one quick test:

SQL
SELECT first_name, IF(commission IS NULL, 'Salary only', 'Salary + commission') AS pay_typeFROM employeesWHERE dept_id = 2 OR emp_id = 101;
ResultMySQL 8.4
first_namepay_type
AshaSalary only
VikramSalary + commission
NehaSalary + commission
ArjunSalary + commission
4 rows in set

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.

Expected resultMySQL 8.4
first_namedept
Meera0
Amit1
Asha1
Karan1
Priya1
Rahul1
Arjun2
Neha2
Vikram2
Kavya3
Rohan3
Sneha4
12 rows in set
Hint 1

COALESCE(dept_id, 0).

Quick quiz

1. What does COALESCE(NULL, NULL, 5, 7) return?

2. What does NULLIF(10, 10) return?

3. Which function is standard SQL and works in every database?

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.

Leave a Comment