πŸŽ‰ 75% of content is free forever β€” Unlock Premium from $10/mo β†’
CW
Search courses…
πŸ’Ό Servicesℹ️ Aboutβœ‰οΈ ContactView Pricing Plansfrom $10

COALESCE and NULLIF

SQL Database ObjectsNULL Handling🟒 Free Lesson

Advertisement

SQL Database Objects

COALESCE and NULLIF

Master the two most important functions for handling NULL values in SQL.

  • COALESCE β€” Returns the first non-NULL value from a list of expressions
  • NULLIF β€” Returns NULL when two values are equal, preventing errors like division by zero NULL is not an error β€” it's a state. Handle it gracefully.

What Is COALESCE?

DfCOALESCE

COALESCE evaluates a list of expressions in order and returns the first non-NULL value. If all expressions are NULL, it returns NULL. Think of it as a fallback chain β€” SQL tries each value until it finds one that exists.

COALESCE Fallback ChainValue 1NULLnickname = NULLSkipValue 2NULLteam = NULLSkipValue 3UnassignedLiteral valueUse!Result: UnassignedFirst non-NULL value found!COALESCE(NULL, NULL, 'Unassigned')Try each value left-to-right, stop at first non-NULL
-- Basic COALESCE: returns first non-NULL value
SELECT
    first_name,
    COALESCE(nickname, first_name) AS display_name
FROM employees;
-- Multiple fallbacks: department, then team, then 'Unassigned'
SELECT
    employee_name,
    COALESCE(department, team, 'Unassigned') AS assignment
FROM staff;
-- Replacing NULL in aggregations
SELECT
    department,
    COALESCE(SUM(commission), 0) AS total_commission
FROM employees
GROUP BY department;

What Is NULLIF?

DfNULLIF

NULLIF compares two expressions and returns NULL if they are equal, otherwise it returns the first expression. It's primarily used to prevent errors like division by zero and to convert sentinel values (like 0 or empty strings) into proper NULLs.

-- Prevent division by zero
SELECT
    order_id,
    total_amount,
    quantity,
    total_amount / NULLIF(quantity, 0) AS unit_price
FROM order_items;
-- Convert a default value back to NULL
SELECT
    employee_name,
    NULLIF(bonus, 0) AS actual_bonus
FROM payroll;
-- Combined: COALESCE handles NULL, NULLIF handles zero
SELECT
    employee_name,
    COALESCE(NULLIF(salary, 0), 0) AS salary
FROM payroll
WHERE salary IS NOT NULL;

COALESCE vs CASE WHEN

DfCOALESCE is Syntactic Sugar

COALESCE(a, b, c) is functionally equivalent to a CASE expression that checks for NULL. It's shorter, cleaner, and more readable.

ExpressionEquivalent
COALESCE(a, b, c)CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ELSE c END
COALESCE(x, 0)CASE WHEN x IS NOT NULL THEN x ELSE 0 END
NULLIF(a, b)CASE WHEN a = b THEN NULL ELSE a END

Practical Examples

Employee Directory with Defaults

SELECT
    employee_id,
    first_name || ' ' || last_name AS full_name,
    COALESCE(phone, 'No phone') AS phone,
    COALESCE(email, 'No email') AS email,
    COALESCE(extension, 'N/A') AS extension
FROM employees;

Salary Report with Commission Handling

SELECT
    e.first_name || ' ' || e.last_name AS employee_name,
    e.salary AS base_salary,
    COALESCE(e.commission, 0) AS commission,
    e.salary + COALESCE(e.commission, 0) AS total_compensation,
    CASE
        WHEN e.salary >= 100000 THEN 'Senior'
        WHEN e.salary >= 60000 THEN 'Mid-Level'
        ELSE 'Junior'
    END AS level
FROM employees e;

Division Safety Pattern

-- Always use NULLIF when dividing to prevent runtime errors
SELECT
    department_name,
    total_budget,
    employee_count,
    total_budget / NULLIF(employee_count, 0) AS budget_per_employee
FROM department_stats;

Cleaning Import Data

-- Imported data may have 0 instead of NULL for missing values
SELECT
    customer_id,
    COALESCE(NULLIF(phone, ''), NULLIF(phone, '0'), 'Unknown') AS phone,
    COALESCE(NULLIF(address, ''), 'No address') AS address
FROM imported_customers;

NULL Behavior Quick Reference

ExpressionResultExplanation
COALESCE(NULL, NULL, 5)5First non-NULL found at position 3
COALESCE(NULL, NULL, NULL)NULLAll values are NULL
COALESCE(1, 2, 3)1First value is already non-NULL
NULLIF(5, 5)NULLValues are equal β€” returns NULL
NULLIF(5, 3)5Values differ β€” returns first expression
NULLIF(NULL, NULL)NULLBoth NULL β€” returns NULL
COALESCE(NULLIF(5, 5), 0)0NULLIF returns NULL, COALESCE falls back to 0
5 / NULLIF(0, 0)NULLDivision by zero becomes NULL propagation

Advanced Patterns

Conditional Aggregation with NULLIF

-- Calculate average salary only for departments with more than 3 employees
SELECT
    department_id,
    SUM(salary) / NULLIF(COUNT(*), 0) AS avg_salary
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 3;

Pivoting with COALESCE

-- Pivot monthly sales into columns with NULL replacement
SELECT
    product_id,
    COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 1 THEN amount END), 0) AS jan,
    COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 2 THEN amount END), 0) AS feb,
    COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 3 THEN amount END), 0) AS mar
FROM sales
GROUP BY product_id;

Null-Safe Comparisons

-- NULL-safe equality: COALESCE makes NULLs comparable
SELECT *
FROM employees
WHERE COALESCE(phone, '') = COALESCE(:input_phone, '');

Common Mistakes

MistakeWhy It FailsFix
COALESCE(NULL, NULL, NULL)All values are NULL β€” returns NULLProvide a default as the last argument
NULLIF(0, 0)Returns NULL β€” may cause unexpected results downstreamWrap with COALESCE to supply a fallback
salary / NULLIF(0, 0)0/0 is still 0, not NULLEnsure the divisor is checked, not the dividend
COALESCE(column, 'default') with mixed typesType mismatch if column is INT and default is STRINGUse matching types in all positions
Using = NULL instead of IS NULLNULL is not equal to anything β€” comparison always returns NULLUse IS NULL or IS NOT NULL for NULL checks
Nested NULLIF without COALESCEIntermediate NULL may propagate unexpectedlyWrap with COALESCE if you need a non-NULL result

Performance Considerations

COALESCE and NULLIF are zero-cost at runtime. The database optimizer inlines them as simple comparisons. There is no performance penalty for using them liberally.

OperationOverhead
COALESCE(a, b)Equivalent to a single NULL check β€” negligible
NULLIF(a, b)Equivalent to a = b comparison β€” negligible
CASE WHEN a IS NOT NULL THEN a ELSE b ENDSame as COALESCE β€” no difference
Nested COALESCE chains (5+ values)Still negligible β€” each is just a NULL check

Portability Notes

FeaturePostgreSQLMySQLSQL ServerOracleSQLite
COALESCEβœ…βœ…βœ…βœ…βœ…
NULLIFβœ…βœ…βœ…βœ…βœ…
ISNULL() (SQL Server)βŒβŒβœ…βŒβŒ
IFNULL() (MySQL)βŒβœ…βŒβŒβŒ
NVL() (Oracle)βŒβŒβŒβœ…βŒ

Always prefer COALESCE over database-specific functions like ISNULL or NVL. COALESCE is ANSI SQL standard and works across all major databases.

When to Use Each

ScenarioUseWhy
Replace NULL with a default valueCOALESCE(col, default)Clean, readable fallback
Prevent division by zeroNULLIF(divisor, 0)Converts 0 to NULL, which propagates correctly
Convert sentinel values to NULLNULLIF(col, sentinel)Strips placeholder values
Multi-level fallbackCOALESCE(a, b, c, d)Chain alternatives in one expression
Conditional defaults with logicCASE WHEN ... ENDWhen you need complex branching beyond simple fallbacks

Key Takeaways

  1. COALESCE returns the first non-NULL value β€” it's your universal NULL replacer
  2. NULLIF returns NULL when two values are equal β€” use it to prevent division by zero
  3. Both functions are ANSI SQL standard and portable across all major databases
  4. COALESCE is functionally equivalent to a CASE expression but far more readable
  5. There is no performance penalty β€” the optimizer inlines both as simple comparisons
⭐

Premium Content

COALESCE and NULLIF

Unlock this lesson and 900+ advanced tutorials with a Premium plan.

🎯End-to-end Projects
πŸ’ΌInterview Prep
πŸ“œCertificates
🀝Community Access

Already a member? Log in

Need Expert SQL Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement