Hello! Welcome to the sixth lesson in our module on SQL fundamentals.
In our last lesson, you learned to use the IN, BETWEEN, and LIKE operators to create more powerful and readable filters. We've been working under the assumption that every piece of data we query has a value. However, in real-world databases—whether you're troubleshooting an API response or debugging an application—data is frequently incomplete.
Today, we'll address this reality. The learning outcome for this lesson is to handle NULL values in queries using IS NULL and IS NOT NULL. This is a critical skill because mishandling missing data is a common source of bugs. Given your interest in the logical foundations of systems, we'll go beyond just the syntax and explore why NULL behaves the way it does, which is a direct consequence of how databases are designed to handle uncertainty.
What Does NULL Really Mean?
First, it's crucial to understand what NULL is—and what it isn't. NULL does not mean zero (0), an empty text string (''), or a string containing a space (' '). NULL is a special marker used in SQL to signify that a value is unknown, missing, or not applicable.
Think of it like this:
- If a user's age is
0, we know their age. They are a newborn. - If a user's name is
''(an empty string), we know their name. It's just an empty name. - If a user's age is
NULL, we have no information about their age. It is unknown.
This distinction is fundamental. The following video explains the differences visually and conceptually.
SQL NULL vs Empty String vs Blank Space (Visually Explained) | #SQL Course 19
Watch this clip from the video 'SQL NULL vs Empty String vs Blank Space' by Data with Baraa. It does an excellent job of clarifying the conceptual differences between these values.
Please watch the following segments: 00:00 - 01:19: The introduction, which explains the core idea of NULL as an 'unknown' value versus an empty string as a 'known, but empty' value. 04:03 - 05:46: The side-by-side comparison table. This is a great summary of the differences in meaning, storage, and how you search for them. 05:46 - 06:07: This part directly addresses our main topic, stating that you must use IS NULL to search for NULL values.
The Logic of the Unknown: Why column = NULL Fails
Now for the "why". A common mistake for beginners is to try filtering for NULL values using the equality operator, like this:
-- This query will NOT work as expected!
SELECT *
FROM customers
WHERE phone_number = NULL;
This query will likely return no rows, even if there are customers with NULL phone numbers. To understand why, we need to touch on a core concept in database theory: three-valued logic (3VL).
In standard boolean logic (like in the C language), a comparison is either TRUE or FALSE. SQL, because of NULL, operates on a three-valued logic system:
TRUEFALSEUNKNOWN
When you compare something to NULL, the database engine can't definitively say the result is TRUE or FALSE. Is the unknown value of phone_number equal to the unknown value of NULL? Maybe, maybe not. The result of this uncertainty is UNKNOWN. Even the comparison NULL = NULL results in UNKNOWN, because the two unknown values are not necessarily the same.
The WHERE clause in a SQL query only includes rows for which the condition evaluates to TRUE. Rows that evaluate to FALSE or UNKNOWN are both discarded.
This is a subtle but powerful concept. The following article explains it brilliantly.
The article 'Three-Valued Logic of SQL' from the Modern SQL website provides a clear, logical explanation for why NULL behaves this way. It's the key to truly understanding how to work with it.
Read the following two sections: 'Comparisons to null': This section explains why NULL = NULL results in UNKNOWN and introduces IS NULL as the correct predicate. 'General Rule: where, having, when, etc.': This section is crucial. It explains that the WHERE clause only accepts TRUE conditions, which is why your col = NULL filter fails.
The Solution: IS NULL and IS NOT NULL
Since standard comparison operators don't work, SQL provides a special syntax for this exact purpose: IS NULL and IS NOT NULL.
These operators are designed specifically to test whether a value is NULL. They are the correct and only reliable way to filter for missing or existing data. Unlike =, >, or !=, these predicates always return TRUE or FALSE.
WHERE column_name IS NULL: Finds all rows where the value isNULL.WHERE column_name IS NOT NULL: Finds all rows where the value is anything other thanNULL.
Let's see this in action.
SQL NULL Functions | COALESCE, ISNULL, NULLIF, IS (NOT) NULL | #SQL Course 18
This video from Data with Baraa demonstrates the practical use of IS NULL and IS NOT NULL to filter a table.
Watch the segment from 00:44:52 to 00:46:59. It provides clear, practical examples of both IS NULL and IS NOT NULL in a WHERE clause.
As you saw in the video, the syntax is straightforward.
To find all customers who do not have a score:
SELECT *
FROM sales.customers
WHERE score IS NULL;
To find all customers who do have a score:
SELECT *
FROM sales.customers
WHERE score IS NOT NULL;
Test your understanding!
You are a technical support executive looking into a service_tickets table. This table has a closed_at timestamp column, which is NULL if the ticket is still open. Write a query to retrieve all tickets that are still open.
Show answer
SELECT *
FROM service_tickets
WHERE closed_at IS NULL;
An Important Pitfall: NOT IN with NULL
Understanding three-valued logic helps you avoid subtle but severe bugs. A classic example is using NOT IN with a subquery or list that might contain a NULL value.
Consider this query:
SELECT *
FROM customers
WHERE city NOT IN ('London', 'Paris', NULL);
You might expect this to return all customers whose city is not London or Paris. It will return nothing.
Here's why, broken down for a customer in 'New York':
- The database checks
'New York' NOT IN ('London', 'Paris', NULL). - This is equivalent to:
'New York' != 'London'(TRUE)AND'New York' != 'Paris'(TRUE)AND'New York' != NULL(UNKNOWN). - The final result is
TRUE AND TRUE AND UNKNOWN, which evaluates toUNKNOWN. - Since the
WHEREclause requiresTRUE, the row for 'New York' is rejected.
This happens for every row, so the query returns an empty set. This is a logical puzzle that stumps even experienced developers. Always be cautious when using NOT IN with a column or list that could contain NULLs.
Conclusion
Excellent! You've now learned one of the most fundamental and frequently misunderstood concepts in SQL. Mastering NULL is a huge step toward writing robust, bug-free queries.
Key Takeaways:
NULLrepresents an unknown or missing value; it is not0or an empty string.- Because of Three-Valued Logic (3VL), standard comparisons with
NULL(e.g.,column = NULLorcolumn != NULL) result inUNKNOWN. - A
WHEREclause only keeps rows where the condition isTRUE, discarding bothFALSEandUNKNOWNresults. - To correctly filter for
NULLvalues, you must use the special predicatesIS NULLandIS NOT NULL.
Preview of the Next Lesson:
Now that you can select and filter data, the next step is to control the presentation of that data. In the next lesson, we will learn how to sort your query results using ORDER BY. We will also see how NULL values are handled during sorting, building directly on what you've learned today.