CMD Guide
HomeDatabasesSQL Fundamentals

WHERE Clause

WHERE Clause

A WHERE clause is a per-row boolean test the engine evaluates against each candidate row as it scans the table, keeping only the rows for which the test returns exactly TRUE — rows that return FALSE or UNKNOWN are thrown away. It runs after FROM produces the rows but before SELECT picks the columns, which is why the predicate can reference columns you never put in the output and cannot reference output aliases that don't exist yet.

Worked example: trace the predicate row by row

Take a Products table and ask for in-stock electronics under $500. The engine walks every row, computes the predicate, and admits only the rows where the combined result is TRUE:

SELECT name, price
FROM Products
WHERE category = 'Electronics' AND price < 500;

Evaluating the predicate category = 'Electronics' AND price < 500 against each row:

idnamecategorypricecategory = 'Electronics'price < 500AND resultkept?
1MouseElectronics25TRUETRUETRUEyes
2MonitorElectronics700TRUEFALSEFALSEno
3DeskFurniture300FALSETRUEFALSEno
4WebcamElectronicsNULLTRUEUNKNOWNUNKNOWNno

Only row 1 survives. Note row 4: its price is unknown, so price < 500 is neither TRUE nor FALSE but UNKNOWN, and TRUE AND UNKNOWN is UNKNOWN — so the Webcam is silently dropped even though it is an Electronics item. The engine never told you it had a row it couldn't decide on.

diagram
diagram

Why the naive NULL filter is wrong

A common attempt to also catch the unknown-price rows is to write price != 500 or price <> 500 and assume NULLs come along. They don't. Any comparison operator (=, !=, <, >) applied to NULL yields UNKNOWN, never TRUE, so the row is excluded by both price < 500 and price >= 500. To test for absence you must use the dedicated operator:

-- naive: silently misses the NULL-price row
WHERE category = 'Electronics' AND price < 500

-- explicit: include unknown prices on purpose
WHERE category = 'Electronics' AND (price < 500 OR price IS NULL)

IS NULL / IS NOT NULL are the only operators that return TRUE/FALSE against a NULL; everything else returns UNKNOWN, and WHERE keeps only TRUE.

Pitfalls

Takeaways


Re-authored and deepened for this guide. Synthesized from the SQL standard's three-valued logic (ISO/IEC 9075), the PostgreSQL documentation on the SELECT statement and comparison operators, and the MySQL Reference Manual chapters on WHERE clause optimization and working with NULL values. The original page (single category='Electronics' example, mislabeled java code header, and figures with alt='Image') was replaced with a row-by-row predicate trace, a pipeline diagram, and the NULL/alias/HAVING failure modes a working engineer hits.

🎯 STANDOUT elevation: Why / example / when-not / failure / panel / drills — WHERE Clause

Why this exists / the decision it encodes

WHERE exists to admit only rows whose predicate is exactly TRUE under three-valued logic. It runs after FROM and before SELECT/GROUP — so it sees base columns, not SELECT aliases, and cannot use aggregates (those belong in HAVING). The decision is which rows enter the pipeline at all.

Worked example with numbers or traced SQL/FD

Products: (1 Mouse Elec 25)(2 Monitor Elec 700)(3 Desk Furn 300)(4 Webcam Elec NULL)
WHERE category='Electronics' AND price < 500
Row1: T AND T = T → keep
Row2: T AND F = F → drop
Row3: F AND T = F → drop
Row4: T AND UNKNOWN = UNKNOWN → drop (NULL price)
Fix if unknowns wanted: ... AND (price < 500 OR price IS NULL)
Alias trap: WHERE sale_price < 100 fails if sale_price is SELECT alias — repeat expr or CTE.

When NOT / named alternative

Do not use WHERE for aggregate filters — use HAVING. Do not filter outer-join preserved columns in WHERE if you need NULL-padded orphans (use ON). Prefer sargable predicates: bare column vs constant range, not function(column).

Failure mode / ops fingerprint / interview trap

Trap: status='active' OR status!='active' still loses NULL statuses. Ops: reports silently undercount rows with NULL measures because UNKNOWN drops them. Interview: "NULL = NULL is false" — actually comparison yields UNKNOWN; only IS NULL tests absence.

Domain judgment (K11 theory-bridge / K12 concurrency / K13 query-judgment)

K13: every WHERE shape is also an access-path decision (sargability). Three-valued logic is correctness, not style.

Hostile-panel drills (with model answers)

Q1. What three outcomes can a WHERE predicate have, and which keep the row?
Model answer: TRUE, FALSE, UNKNOWN. Only TRUE keeps the row; FALSE and UNKNOWN both discard.

Q2. Why can't you reference SELECT aliases in WHERE?
Model answer: Logical processing order: FROM → WHERE → GROUP → HAVING → SELECT → ORDER. Aliases are created at SELECT, after WHERE has already run.

Q3. Rewrite DATE(created_at)='2026-06-29' to a sargable range.
Model answer: WHERE created_at >= '2026-06-29' AND created_at < '2026-06-30' so the index on created_at can seek a range of raw values.

🤖 Don't fully get this? Learn it with Claude

Stuck on WHERE Clause? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **WHERE Clause** (Databases) and want to truly understand it. Explain WHERE Clause from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **WHERE Clause** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **WHERE Clause** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **WHERE Clause** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes