When a WHERE clause mixes AND with OR, the query follows its own grouping rules, not the way a sentence sounds in English. In standard SQL, AND is worked out before OR. Brackets let you decide the grouping yourself.
Reading and writing queries with a filter sits in databases and query reasoning. The lessons write a simple SELECT filter and combine conditions with the correct Boolean grouping build the skill step by step.
Why does the wrong grouping happen?
In English we say “science fiction or fantasy books published after 2015” and our brain groups it as (science fiction or fantasy) and after 2015. SQL does not read English. It sees three conditions joined by OR and AND and applies its precedence: AND first, then OR.
That means the same words can mean two different queries. Only brackets make the meaning certain.
Worked example
A table called Books holds five rows.
| id | title | genre | year |
|---|---|---|---|
| 1 | Dune | SciFi | 1965 |
| 2 | Nova | Fantasy | 2019 |
| 3 | Orbit | SciFi | 2021 |
| 4 | Ember | Fantasy | 2010 |
| 5 | Drift | Mystery | 2022 |
Goal: list the titles of SciFi or Fantasy books published after 2015.
Attempt A, no brackets:
SELECT title
FROM Books
WHERE genre = 'SciFi' OR genre = 'Fantasy' AND year > 2015;
Step 1. AND binds first, so the query reads as: genre = ‘SciFi’ OR (genre = ‘Fantasy’ AND year > 2015).
Step 2. Every SciFi row qualifies, whatever its year: Dune (1965) and Orbit (2021).
Step 3. Fantasy rows qualify only if the year is after 2015: Nova (2019) yes, Ember (2010) no.
Result of A: Dune, Nova, Orbit. That is three rows, and Dune is not after 2015.
Attempt B, with brackets:
SELECT title
FROM Books
WHERE (genre = 'SciFi' OR genre = 'Fantasy') AND year > 2015;
Step 1. The bracket first: rows 1 to 4 are SciFi or Fantasy (Drift is Mystery, so it is out).
Step 2. Then year > 2015 is applied to those rows: Nova (2019) and Orbit (2021) stay. Dune (1965) and Ember (2010) drop out.
Result of B: Nova, Orbit. Two rows, which is what the goal asked for.
The mistakes to watch for
Mistake 1: no brackets. As in attempt A, the query runs, but it answers a different question. Nothing warns you, because the query is valid.
Mistake 2: AND where the English says “or”. Writing genre = 'SciFi' AND genre = 'Fantasy' asks for a book that is both genres in a single field. No row can be both, so zero rows come back.
Correction: say the condition out loud in words, decide the groups, then write the brackets. If you meant “either of these”, use OR inside a bracket.
A routine that catches this every time
- Write the question as one sentence and underline the groups.
- Write the query with brackets around each group.
- Take five sample rows and tick which qualify by hand.
- Run or trace the query and compare with your ticks.
The same habit of tracing by hand is what the pseudocode trace trainer and the Python reasoning sandbox practise on small algorithms.
Self-check
Use the Books table above.
1. What does SELECT title FROM Books WHERE genre = 'Mystery' OR year < 2000; return?
Show answer
Drift (Mystery) and Dune (1965, which is before 2000). Both conditions are joined by OR, so a row needs only one of them. The result is Dune and Drift.2. Write a query for SciFi books after 2000 that have an id greater than 1.
Show answer
`SELECT title FROM Books WHERE genre = 'SciFi' AND year > 2000 AND id > 1;` Only Orbit qualifies. All three conditions use AND, so no brackets are needed, but a row must pass every one.3. A query needs Fantasy books, or any book after 2020. Which rows does WHERE genre = 'Fantasy' OR year > 2020 return?
Show answer
Nova and Ember (Fantasy), plus Orbit (2021) and Drift (2022). Dune is neither Fantasy nor after 2020. The result has four rows.Where to go next
Practise the grouping skill in explain why a query returns no rows, and if logic operators themselves feel slippery, revisit evaluate a logical expression with parentheses.
For a student who can write SQL but keeps second-guessing the result, online one-to-one Computer Science tuition can start from your own queries in a paid trial lesson from RM80.