Where WHERE fits
In session b1 you ran SELECT ... FROM ... and got the whole table back. That is fine for eight products, hopeless for a million orders. WHERE sits right after FROM and keeps only the rows that pass a test you write - "price under 18", "country is Canada", "plan is Pro". Everything you already know still works; you are just adding one line that does the filtering.
WHERE reflex - comparison operators, AND/OR/NOT to combine tests, and the pattern-and-set family (LIKE, IN, BETWEEN, IS NULL). By the end you can carve any precise slice of Daybreak you want and hand it over.
WHERE and the comparison operators 7 min live
A WHERE clause is a test applied to every row, one at a time. If the test is true, the row comes back; if false, it is dropped. The tests are built from comparison operators you already know from a calculator: = equals, != not equal, > greater, < less, >= and <=. Text goes in single quotes; numbers do not.
LiveFilter by an exact match3 min▶
Here is the funnel from the diagram, live. This asks for only the rows where category equals 'Coffee'. Press ▶ Run, then change 'Coffee' to 'Equipment' or 'Add-on' and run again - watch which rows survive.
SELECT name, category, price FROM products WHERE category = 'Coffee';
'Coffee' is text, so it needs single quotes. Miss them and SQLite thinks Coffee is a column name and errors. Numbers like 18 are bare, no quotes.
LiveFilter by a number range3 min▶
Comparison operators shine on numbers. This keeps only products priced below 18. Change < to >=, or the 18 to 25, and re-run to feel how the operator picks the rows.
SELECT name, price FROM products WHERE price < 18;
"Show me everything under our free-shipping threshold." That request is a one-line WHERE price < 18. Pricing pages, discount tiers, "budget picks" carousels - all of it starts as a comparison filter on one number column. The clause you just ran is quietly powering shopping sites everywhere.
Combining tests: AND, OR, NOT 6 min live
One test is useful; combining them is where filtering gets sharp. AND means a row must pass both tests. OR means it needs pass either. NOT flips a test. String enough together and you can describe almost any slice of customers in one line - "Pro plan, in the USA, signed up this year".
| Connector | Row is kept when... | Plain-English read |
|---|---|---|
| AND | both tests are true | "Pro and in the USA" - stricter, fewer rows |
| OR | at least one test is true | "Canada or UK" - looser, more rows |
| NOT | the test is false | "NOT cancelled" - everything except the match |
LiveAND - both tests must pass3 min▶
This finds customers who are on the Pro plan and based in the USA - both conditions, joined by AND. Because both must be true, AND narrows the result. Try changing 'USA' to 'UK', or swap AND for OR and watch the row count grow.
SELECT name, city FROM customers WHERE plan = 'Pro' AND country = 'USA';
LiveOR - either test passes3 min▶
Here OR keeps a customer if they are in Canada or the UK. Notice you repeat the column name on both sides of OR - country = 'Canada' OR country = 'UK', not country = 'Canada' OR 'UK'. Part 3 shows IN, a tidier way to write exactly this.
SELECT name, country FROM customers WHERE country = 'Canada' OR country = 'UK';
AND before OR - just like times-before-plus in maths. Wrap the OR group in parentheses to be explicit: WHERE plan = 'Pro' AND (country = 'Canada' OR country = 'UK'). Clear beats clever.
Pattern and set matching: LIKE, IN, BETWEEN, IS NULL 8 min live
Four specialist operators cover the filters that = cannot. LIKE matches text patterns with wildcards. IN checks membership in a list. BETWEEN tests a range, endpoints included. IS NULL finds missing values - and it is the one people get wrong most often.
LiveLIKE - match a text pattern3 min▶
The % wildcard means "any run of characters". So '%Espresso%' matches any product name that contains "Espresso" anywhere - start, middle, or end. Run it, then try 'Cold%' (starts with Cold) or '%Beans' (ends with Beans).
SELECT name FROM products WHERE name LIKE '%Espresso%';
% matches any number of characters; _ matches exactly one. In SQLite, LIKE is case-insensitive for plain ASCII letters, so '%espresso%' matches too.
LiveIN - match any value in a list2 min▶
Remember the repetitive OR from Part 2? IN collapses it into one clean list. This is the exact same result - Canada or UK customers - written the tidy way. Add 'Germany' to the list and re-run.
SELECT name, country
FROM customers
WHERE country IN ('Canada','UK');
LiveBETWEEN - a range, endpoints included2 min▶
BETWEEN 15 AND 20 keeps every price from 15 to 20 inclusive of both ends. It is the readable way to write price >= 15 AND price <= 20. Watch the boundaries: a product priced exactly 15 or exactly 20 is kept.
SELECT name, price FROM products WHERE price BETWEEN 15 AND 20;
LiveIS NULL - find the missing values3 min▶
In Daybreak, only Coffee products have a roast; Equipment and Add-on rows store NULL there. To find them you must write roast IS NULL - never roast = NULL. This is the number-one beginner trap, so it earns its own callout below.
SELECT name FROM products WHERE roast IS NULL;
Why = NULL silently returns nothing. NULL means "unknown", and in SQL anything compared to unknown is itself unknown - never true. So roast = NULL is never true for any row and quietly returns zero rows, no error. Teams have shipped reports that "found no missing data" for months because of exactly this. Always use IS NULL and IS NOT NULL.
Build-along: a customer segment ★ 12 min · everyone builds
Daybreak's marketing lead wants a segment: "our Pro customers in the USA, newest signups first." That is two filters joined by AND, plus an ORDER BY from session b1. Let us assemble it one clause at a time.
Start with the table: SELECT name, city, signup_date FROM customers; - everyone, all columns you care about.
Add the first filter: WHERE plan = 'Pro'. Now only Pro customers remain.
Tighten with AND country = 'USA'. Both tests must pass - the segment narrows.
Order it: ORDER BY signup_date DESC puts the newest signups on top. That is the segment.
SELECT name, city, signup_date FROM customers WHERE plan = 'Pro' AND country = 'USA' ORDER BY signup_date DESC;
Every "audience" is a WHERE clause. The segments marketing teams obsess over - "high-value UK subscribers", "at-risk trial users" - are, underneath the dashboard, exactly this: a few WHERE conditions and a sort. Learn to write them fast and you become the person who answers "can you pull a list of..." in thirty seconds.
Your turn: three filters, your queries ★ 10 min · build your own
No hand-holding now. Each editor answers one question - run it, tweak it, break it, fix it. That run-fix-run loop is the whole skill, and errors are cheap here.
LiveQ1 · Coffees under $183 min▶
Two filters joined by AND: the category is Coffee, and the price is below 18. Run it, then loosen the price to 25 and see who joins.
SELECT name, price FROM products WHERE category = 'Coffee' AND price < 18;
LiveQ2 · The equipment items (roast is missing)3 min▶
Equipment has no roast, so filter on both the category and the missing value. Notice the IS NULL - never = NULL.
SELECT name, category, roast FROM products WHERE category = 'Equipment' AND roast IS NULL;
Self-studyQ3 · Customers who signed up in 20262 min▶
A neat trick: dates are stored as text like '2026-03-14', so LIKE '2026%' matches every date that starts with 2026. Later sessions use proper date functions, but this pattern is handy and readable.
SELECT name, signup_date FROM customers WHERE signup_date LIKE '2026%' ORDER BY signup_date;
Try it yourself - this week ◐ 20-30 min total
- List every Dark-roast coffee by name and price. (Hint: two filters,
roast = 'Dark'.) - Find all customers who are not in the USA. Try it two ways: with
!=and withNOT country = 'USA'. - Pull products priced
BETWEEN 20 AND 30, most expensive first. - Find every product whose name contains the word "Blend" using
LIKE. - Bring one segment question about Daybreak you cannot yet answer to session b3 - odds are it needs counting or summing, which is exactly what b3 delivers.
Official sources covered
This session teaches the filtering core of the major free SQL curricula, run on live Daybreak data instead of screenshots. Certificates and graded problem sets stay on the official sites (linked below). This page covers:
Three questions before you go 🎯 ◐ 90 seconds
1 · What does a WHERE clause do?
WHERE filters rows - it tests each row and keeps the ones that pass, before grouping happens. SELECT picks columns; ORDER BY sorts.
2 · WHERE name LIKE '%Espresso%' matches names that...
The % wildcards on both sides mean "any characters before and after", so it matches any name containing Espresso anywhere in it.
3 · How do you filter for rows where roast has no value?
Use IS NULL, never = NULL. Comparing anything to NULL yields "unknown", never true, so = NULL silently returns zero rows with no error.