WHERE: Filtering Your Results
Only show rows that match a condition — the most useful clause in SQL
SELECT * gives you everything. Most of the time you want something more specific: just the paid users, just orders from this week, just products under £20. WHERE is how you filter.
The mental model
WHERE in action
-- Only pro users SELECT name, email FROM users WHERE plan = 'pro'; -- Orders over £50 SELECT * FROM orders WHERE amount > 50; -- Users who signed up after a certain date SELECT name FROM users WHERE created_at > '2026-01-01'; -- Find a specific user by id SELECT * FROM users WHERE id = 42;
WHERE is a bouncer with a clipboard
Imagine every row in your table walking up to a bouncer. The bouncer has one rule: "plan must equal pro." Sarah arrives — plan=pro. In she goes. Alex arrives — plan=free. Turned away. Priya arrives — plan=pro. In she goes. The WHERE clause is that bouncer. Only rows that pass the condition get into the result.
Comparison operators
- = (equals) — WHERE plan = 'pro' — exact match. Note: SQL uses single quotes for text, not double.
- != or <> (not equal) — WHERE plan != 'free' — everything except free.
- > < >= <= (numeric) — WHERE amount >= 100 — orders of £100 or more.
- LIKE (pattern matching) — WHERE email LIKE '%@gmail.com' — all Gmail users. % is a wildcard matching anything.
- IN (list of values) — WHERE plan IN ('pro', 'enterprise') — either plan type.
- IS NULL / IS NOT NULL — WHERE cancelled_at IS NULL — only rows where that column has no value.
- BETWEEN — WHERE amount BETWEEN 10 AND 50 — inclusive range.
Combining conditions: AND, OR, NOT
Multiple conditions in WHERE
-- Pro users who signed up this year SELECT name FROM users WHERE plan = 'pro' AND created_at >= '2026-01-01'; -- Free OR trial users SELECT name FROM users WHERE plan = 'free' OR plan = 'trial'; -- All users except admins SELECT name FROM users WHERE NOT role = 'admin'; -- Complex: active pro users with orders over £100 SELECT u.name FROM users u JOIN orders o ON o.user_id = u.id WHERE u.plan = 'pro' AND o.amount > 100 AND o.status = 'paid';
WHERE runs before SELECT
SQL processes FROM first (get the table), then WHERE (filter rows), then SELECT (pick columns). This matters when debugging: if your WHERE clause is wrong, your SELECT result will be wrong too. Always check you're filtering what you think you're filtering.
Try this
Write three WHERE queries: (1) all pro users, (2) all orders over £30, (3) all users whose email contains "gmail". Then combine them: all pro users who placed an order over £30 — this will require a JOIN (coming in lesson 6).