Working with NULL pops up in all sorts of scenarios: from dealing with missing data in reports to filtering and sorting. If you had to choose between having no value in a table and some weird number like 9999, most folks would pick NULL—yeah, it's not the most convenient, but at least it's honest. Let's check out a few typical cases.
Example: Sorting Products with Missing Prices
Imagine we're running an online store, and we've got a products table:
| product_id | name | price |
|---|---|---|
| 1 | Phone | 45000 |
| 2 | Laptop | NULL |
| 3 | Camera | 25000 |
| 4 | Smart Watch | NULL |
We want to sort products by price, but products without a price (NULL) should go at the end.
SELECT product_id, name, price
FROM products
ORDER BY price ASC NULLS LAST;
Result:
| product_id | name | price |
|---|---|---|
| 3 | Camera | 25000 |
| 1 | Phone | 45000 |
| 2 | Laptop | NULL |
| 4 | Smart Watch | NULL |
Notice the key part NULLS LAST. By default, PostgreSQL already puts NULL values at the end for ASC (NULLS LAST), and at the beginning for DESC (NULLS FIRST). Specifying NULLS LAST after ASC explicitly locks this behavior in and doesn't change the result — but it's useful when you want to make your intent explicit or override the default.
Example: Filtering Students Without a Birth Date
We've got a students table, and we want to select only those who don't have a birth date set.
| student_id | name | birth_date |
|---|---|---|
| 1 | Otto Art | 2000-01-15 |
| 2 | Anna Song | NULL |
| 3 | Alex Lin | 1999-05-10 |
| 4 | Maria Chi | NULL |
Query:
SELECT student_id, name
FROM students
WHERE birth_date IS NULL;
Result:
| student_id | name |
|---|---|
| 2 | Anna Song |
| 4 | Maria Chi |
We successfully pulled info about students whose birth date is unknown.
Examples of Using Functions to Handle NULL
Example: Calculating the Total Amount Considering Possible NULLs
The orders table stores order amounts. But sometimes the data isn't filled in, and we need to treat those cases as if the amount is 0.
Sample data:
| order_id | customer_name | order_amount |
|---|---|---|
| 1 | Alex | 1200 |
| 2 | Maria | 2500 |
| 3 | Max | NULL |
| 4 | Xena | 3100 |
Query:
SELECT SUM(COALESCE(order_amount, 0)) AS total_amount
FROM orders;
Result:
| total_amount |
|---|
| 6800 |
We use COALESCE(order_amount, 0) to swap NULL for 0 before summing. This helps avoid errors or wrong totals.
Example: Showing Text Instead of NULL
| customer_name | order_amount |
|---|---|
| Alex | 1200 |
| Maria | 2500 |
| Max | NULL |
| Xena | 3100 |
In the report, we need to show the text "Not specified" for all empty data instead of NULL.
SELECT
customer_name,
COALESCE(order_amount::TEXT, 'Not specified') AS order_status
FROM orders;
Result:
| customer_name | order_status |
|---|---|
| Alex | 1200 |
| Maria | 2500 |
| Max | Not specified |
| Xena | 3100 |
COALESCE() lets you show whatever text you want if the value is NULL.
Trickier Scenarios with NULL
| customer_name | order_amount |
|---|---|
| Alex | 1200 |
| Maria | 2500 |
| Max | NULL |
| Xena | 3100 |
Our task is to sort orders so that orders with missing amounts come first, then by descending order from biggest to smallest amount.
SELECT customer_name, order_amount
FROM orders
ORDER BY order_amount DESC NULLS FIRST;
Result:
| customer_name | order_amount |
|---|---|
| Max | NULL |
| Xena | 3100 |
| Maria | 2500 |
| Alex | 1200 |
Here we used NULLS FIRST to put NULL values before everything else.
Example: Filtering Data with Replacing NULL Values
| student_id | name | birth_date |
|---|---|---|
| 1 | Otto Art | 2000-01-15 |
| 2 | Anna Song | NULL |
| 3 | Alex Lin | 1999-05-10 |
| 4 | Maria Chi | NULL |
In some reports, you need to show only rows where the value is filled in or replace it with "Unknown" if it's NULL.
SELECT
student_id,
name,
COALESCE(birth_date::TEXT, 'Unknown') AS birth_date_info
FROM students;
Result:
| student_id | name | birth_date_info |
|---|---|---|
| 1 | Otto Art | 2000-01-15 |
| 2 | Anna Song | Unknown |
| 3 | Alex Lin | 1999-05-10 |
| 4 | Maria Chi | Unknown |
This is especially handy when making reports where it's important to show that data is missing.
Practical Tips
Working with NULL takes extra attention. Here are a few handy tips:
- Use
IS NULLandCOALESCE()to check for and replace missing values. - Remember that aggregate functions ignore
NULL, except forCOUNT(*). - For sorting, don't forget about the keywords
NULLS FIRSTandNULLS LAST. - In reports, always say how you handle
NULLso your teammates aren't confused.
Knowing this stuff will help you not just write solid queries, but also impress at interviews. Being able to handle real data is always valued more than just theory!
GO TO FULL VERSION