Filtering · Episode 2

But I only want these customers

WHEREcomparison operatorsANDORNOTINBETWEENLIKENULL
The story

The marketing team pings Harry: “Can you get me just the customers in India?”

Harry

Easy. SELECT * FROM customers, then I’ll just eyeball it and copy out the India ones.

Hermione

Works fine for 12 rows. NOVA has a couple million. You need the database to do the picking, not your eyes.

The concept

This is what WHERE is for. It runs after FROM, and it asks every single row the same yes-or-no question. Only the rows that answer “yes” make it into the result.

Which rows are allowed to stay?

Build the query
query.sql
SELECT * FROM customers WHERE country = 'India';
Result2 rows
idnamecountry
1Alice SharmaIndia
6Farah KhanIndia

Marketing: “Actually, add the USA too.” You could write two conditions joined with OR:

query.sql
SELECT * FROM customers
WHERE country = 'India' OR country = 'USA';

That works, but it gets unwieldy fast if marketing keeps adding countries. IN says the same thing more cleanly — “country is one of these”:

query.sql
SELECT * FROM customers
WHERE country IN ('India', 'USA');

Marketing: “One more thing — only customers who signed up in 2023, not 2022.” Stack a second condition with AND. Both have to be true for a row to survive:

query.sql
SELECT name, country, signup_date FROM customers
WHERE country IN ('India', 'USA')
  AND signup_date >= '2023-01-01';
Run it
query.sql

Running…

George Lee is gone from the results — he’s from the USA, but he signed up in November 2022, so the second condition filters him out. AND means both conditions have to hold, not either one.

A few more ways to ask

WHERE has a few more tools worth knowing before we move on.

A date range reads naturally with BETWEEN (both ends included):

query.sql
SELECT name, signup_date FROM customers
WHERE signup_date BETWEEN '2023-01-01' AND '2023-03-31';
Result5 rows
namesignup_date
Alice Sharma2023-01-15
Bob Turner2023-02-20
Chloe Martin2023-03-05
Diego Fernandez2023-01-30
Ivan Petrov2023-02-14

Searching inside text uses LIKE, where % means “anything, any length.” This finds every name starting with “J”:

query.sql
SELECT name FROM customers WHERE name LIKE 'J%';
Result1 row
name
Julia Souza

And to find missing values — like customers with no phone number on file — there’s IS NULL:

query.sql
SELECT name, phone FROM customers WHERE phone IS NULL;
Result3 rows
namephone
Chloe MartinNULL
Farah KhanNULL
Julia SouzaNULL
Try it: What happens if you write WHERE phone = NULL instead of WHERE phone IS NULL?
experiment.sql

Run your query to see results here.

It runs without an error — and comes back completely empty. Zero rows, even though three customers clearly have no phone number. That’s not a bug: NULL means “unknown”, not “empty string” or “zero”. Asking “does this equal unknown?” is itself unknown, never true — not even when compared to another NULL. So SQL gives NULL its own comparisons: IS NULL and IS NOT NULL.

One more operator

Last one: NOT flips a condition. “Everyone except the USA” reads either way:

query.sql
SELECT name, country FROM customers
WHERE NOT country = 'USA';

-- same result:
SELECT name, country FROM customers
WHERE country <> 'USA';
Your turn

Marketing is back with one more request: customers from India or Brazil, who signed up before June 2023, and — since they want to call these customers — only ones where NOVA actually has a phone number on file.

Opens in a new window, full width — come back here once you’re done.
Hint 1

You'll need to combine more than one condition — how do you require all of them at once?

Hint 2

Think: IN for the two countries, a comparison for the date, and an IS NOT NULL for the phone.

Hint 3

WHERE country IN ('India', 'Brazil') AND signup_date < '2023-06-01' AND phone IS NOT NULL;

Solution
solution.sql

Running…

Debrief

Farah and Julia both matched on country, and Farah also matched on date — but both are missing a phone number, so the third condition drops them. That’s the whole idea of WHERE: every condition is its own yes/no question, and you chain them with AND/OR to describe exactly the rows you mean.

One thing to remember

WHERE filters rows one at a time. Combine conditions with AND/OR, use IN for multiple exact matches, BETWEEN for ranges, LIKE for patterns — and always check for missing values with IS NULL / IS NOT NULL, never = NULL.