PostgreSQL CASE, COALESCE and NULL Handling: Practical SQL Guide
In PostgreSQL, CASE, COALESCE, and NULL-handling functions help you manage missing values, create conditional results, categorize data, and build meaningful business reports.
These concepts are useful for data analysts, SQL developers, reporting, and technical interviews.
What Is CASE in PostgreSQL?
The CASE expression works like an IF-THEN-ELSE statement. It checks conditions and returns a result based on the first matching condition.
Syntax:
SELECT
column_name,
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
ELSE default_result
END AS result_column
FROM table_name;
1. Categorize Employees Based on Salary
Consider an employees table with these columns: employee_id, employee_name, department, and salary.
SELECT
employee_name,
salary,
CASE
WHEN salary >= 70000 THEN 'High Salary'
WHEN salary >= 50000 THEN 'Medium Salary'
ELSE 'Low Salary'
END AS salary_category
FROM employees;
The query assigns a salary category to each employee.
Example:
| employee_name | salary | salary_category |
|---|---|---|
| Arjun | 75000 | High Salary |
| Rahul | 60000 | Medium Salary |
| Priya | 40000 | Low Salary |
The conditions are checked from top to bottom. Once a condition matches, PostgreSQL returns its result.
2. Use CASE with GROUP BY
You can use CASE to group records into categories and calculate totals.
SELECT
CASE
WHEN salary >= 70000 THEN 'High'
WHEN salary >= 50000 THEN 'Medium'
ELSE 'Low'
END AS salary_category,
COUNT(*) AS employee_count
FROM employees
GROUP BY
CASE
WHEN salary >= 70000 THEN 'High'
WHEN salary >= 50000 THEN 'Medium'
ELSE 'Low'
END;
This query returns the number of employees in each salary category.
3. Use CASE for Conditional Aggregation
Conditional aggregation calculates different metrics based on specific conditions.
SELECT
department,
COUNT(*) AS total_employees,
COUNT(*) FILTER (WHERE salary >= 60000) AS employees_earning_60000_or_more,
SUM(CASE WHEN salary >= 60000 THEN salary ELSE 0 END) AS qualifying_salary_total
FROM employees
GROUP BY department;
This query returns the total number of employees, the number earning at least 60000, and the combined salaries of those qualifying employees for each department.
PostgreSQL also supports the FILTER clause for conditional aggregation.
What Is NULL in PostgreSQL?
NULL represents a missing or unknown value. It is not the same as zero, an empty string, or the word NULL stored as text.
For example, a table might contain employees whose bonus has not been recorded.
| employee_name | salary | bonus |
|---|---|---|
| Rahul | 60000 | 5000 |
| Priya | 40000 | NULL |
| Arjun | 75000 | 10000 |
Because Priya's bonus is NULL, its value is unknown or missing.
4. Find NULL Values Using IS NULL
Use IS NULL to identify missing values.
SELECT employee_name, bonus
FROM employees
WHERE bonus IS NULL;
To find records where the bonus is available:
SELECT employee_name, bonus
FROM employees
WHERE bonus IS NOT NULL;
Do not use bonus = NULL to check for missing values. Use IS NULL or IS NOT NULL.
5. Replace NULL Values Using COALESCE
COALESCE() returns the first non-NULL value from its arguments.
Syntax:
COALESCE(value1, value2, default_value)
Example:
SELECT
employee_name,
salary,
bonus,
COALESCE(bonus, 0) AS bonus_display
FROM employees;
If an employee's bonus is NULL, the result displays zero instead.
Example:
| employee_name | bonus | bonus_display |
|---|---|---|
| Rahul | 5000 | 5000 |
| Priya | NULL | 0 |
| Arjun | 10000 | 10000 |
Remember that COALESCE() changes the value returned by the query, not the original stored data.
6. Calculate Total Compensation with COALESCE
Suppose NULL bonuses should be treated as zero when calculating total compensation.
SELECT
employee_name,
salary,
COALESCE(bonus, 0) AS bonus,
salary + COALESCE(bonus, 0) AS total_compensation
FROM employees;
Without COALESCE(), adding a NULL bonus to salary produces NULL. With COALESCE(), the missing bonus is treated as zero for this calculation.
Only use zero as a replacement when it makes sense for the business requirement.
7. Use NULLIF to Avoid Division by Zero
NULLIF(value1, value2) returns NULL when both values are equal. Otherwise, it returns the first value.
Example:
SELECT
department,
total_sales,
total_orders,
total_sales / NULLIF(total_orders, 0) AS average_order_value
FROM sales_summary;
If total_orders is zero, NULLIF(total_orders, 0) returns NULL, preventing a division-by-zero error.
For decimal results, use a numeric value such as 100.0 where needed to avoid unintended integer division.
8. Understand COUNT with NULL Values
PostgreSQL handles NULL differently depending on the aggregate function.
SELECT
COUNT(*) AS total_rows,
COUNT(bonus) AS recorded_bonuses
FROM employees;
COUNT(*)counts all rows.COUNT(bonus)counts only rows wherebonusis not NULL.SUM(bonus)ignores NULL bonus values.
This distinction is important when calculating totals and data-quality metrics.
9. Calculate Missing-Value Counts
You can use conditional aggregation to count missing values in a column.
SELECT
COUNT(*) AS total_employees,
COUNT(*) FILTER (WHERE bonus IS NULL) AS missing_bonus_count,
COUNT(*) FILTER (WHERE bonus IS NOT NULL) AS available_bonus_count
FROM employees;
This is useful for data cleaning and checking data completeness before analysis.
10. CASE vs COALESCE vs NULLIF
| Expression | Purpose | Example |
|---|---|---|
CASE |
Returns values based on conditions | Categorize salaries |
COALESCE |
Returns the first non-NULL value | Replace a missing bonus with zero |
NULLIF |
Returns NULL when two values are equal | Avoid division by zero |
Common Mistakes to Avoid
- Using
= NULLinstead ofIS NULL. - Assuming NULL is the same as zero.
- Forgetting that arithmetic involving NULL usually returns NULL.
- Replacing every NULL with zero without checking the business meaning.
- Forgetting that
COUNT(column_name)excludes NULL values. - Writing overlapping
CASEconditions in the wrong order.
Practice Questions
Use the employees table to solve these questions.
- Categorize employees as High, Medium, or Low salary.
- Find employees whose bonus is NULL.
- Display NULL bonuses as zero using
COALESCE(). - Calculate total compensation using salary and bonus.
- Count employees with missing bonuses in each department.
- Use
CASEto label employees earning at least 60000 asEligibleand others asNot Eligible. - Use
NULLIF()to prevent division by zero when calculating an average. - Compare
COUNT(*)andCOUNT(bonus).
Interview Questions
1. What is NULL in PostgreSQL?
NULL represents a missing or unknown value. It is different from zero and an empty string.
2. What is the difference between IS NULL and = NULL?
IS NULL correctly checks whether a value is NULL. Comparisons using = NULL do not evaluate to true.
3. What does COALESCE() do?
It returns the first non-NULL argument.
4. What is the purpose of NULLIF()?
It returns NULL when its two arguments are equal. It can help prevent division-by-zero errors.
5. What is the difference between COUNT(*) and COUNT(column_name)?
COUNT(*) counts all rows, whereas COUNT(column_name) counts only rows where that column is not NULL.
6. Can CASE be used inside an aggregate function?
Yes. For example, SUM(CASE WHEN condition THEN amount ELSE 0 END) calculates a total for rows matching a condition.
Conclusion
Understanding CASE, COALESCE(), NULLIF(), and NULL handling is essential for writing reliable PostgreSQL queries. These techniques help you categorize data, handle missing values, prevent calculation errors, and prepare accurate reports.
Practise these examples with business datasets to strengthen your SQL skills for data analyst and SQL developer roles.
Comments
Post a Comment