1Indentation
When you have 5 ANDs and 3 ORs, write them on separate lines.
WHERE status = 'active'
AND (role = 'admin' OR role = 'mod')
AND created_at > '2023-01-01'
This makes it instantly readable for the next developer.
2Step-by-Step Breakdown
Multiple Conditions. Often, a single condition isn't enough. You need users who are active AND live in Spain. SQL uses plain English logical operators to combine conditions.
The AND Operator. Requires BOTH conditions to be True. 'WHERE country = 'Spain' AND age >= 18;'. If a user is 20 but lives in France, they are excluded.
The OR Operator. Requires AT LEAST ONE condition to be True. 'WHERE role = 'admin' OR role = 'moderator';'. If they are either, they are included.
The Danger of Mixing. If you mix AND and OR without parentheses, you will create catastrophic logic bugs. 'WHERE role = 'admin' OR role = 'mod' AND age > 18' does NOT mean what you think it means.
Knowledge Check. In SQL, which logical operator has higher precedence (meaning it gets evaluated first by the engine before the other)?
- →OR
- →AND
Operator Precedence. AND is evaluated BEFORE OR. The previous query meant: 'Give me admins of ANY age, OR moderators who are over 18'.
Using Parentheses (). ALWAYS use parentheses when mixing operators to enforce your desired logic. 'WHERE (role = 'admin' OR role = 'mod') AND age > 18;'. This forces the OR to evaluate first.
The NOT Operator. Inverts a condition. 'WHERE NOT country = 'USA';'. It is often combined with IN: 'WHERE country NOT IN ('USA', 'Canada');'.
De Morgan's Laws. A logic rule: 'NOT (A AND B)' is exactly the same as 'NOT A OR NOT B'. Understanding this helps simplify massive WHERE clauses.
Summary. Use AND/OR to combine filters, and ALWAYS wrap mixed logic in parentheses.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Mirror Complex Filter Logic in Plain Language for Screen Reader Users
If a UI lets users build filters combining multiple AND/OR conditions (e.g. an advanced search form), announce the resulting logic in plain language, like 'Country is Spain AND Age is over 18', rather than relying purely on visual grouping boxes, which convey nothing to screen reader users.
SEO Implications
- 1
Faceted Search Pages Built with AND/OR Filters Can Create Duplicate Content
E-commerce faceted search combining filters like brand AND color AND price range can generate huge numbers of near-duplicate URLs. Use canonical tags or noindex on narrow filter combinations to avoid diluting SEO value across thousands of thin pages.
Best Practices
Always Wrap Mixed AND/OR Logic in Explicit Parentheses
AND has higher precedence than OR in SQL, so 'WHERE role = 'admin' OR role = 'mod' AND age > 18' does not mean what it visually appears to mean. Explicit parentheses like (role = 'admin' OR role = 'mod') AND age > 18 remove all ambiguity for both the engine and the next developer reading it.
Format Long Chains of AND/OR Conditions on Separate, Indented Lines
A WHERE clause with five ANDs and three ORs is nearly unreadable on one line. Breaking each condition onto its own line, indented under the WHERE keyword, makes the logic scannable at a glance and easier to review in a pull request.
Frequent Bugs
A query meant to filter 'admins or moderators who are adults' silently returns all admins regardless of age.
Without parentheses, 'WHERE role = 'admin' OR role = 'mod' AND age > 18' is evaluated as 'role = admin' OR (role = 'mod' AND age > 18)', because AND binds tighter than OR. Wrap the intended OR group in parentheses: WHERE (role = 'admin' OR role = 'mod') AND age > 18.
A NOT IN filter unexpectedly returns zero rows even though matching rows clearly exist.
If the list passed to NOT IN contains even a single NULL value, the entire condition evaluates to unknown for every row. Filter out NULLs from the list first, or use NOT EXISTS with a correlated subquery instead.
Real-World Examples
Building a Safe, Explicit Filter for Admins and Moderators
An internal tool needed to list every admin (any age) plus moderators who are legal adults, without accidentally including underage moderators.
SELECT * FROM users
WHERE (role = 'admin' OR role = 'mod')
AND age > 18;