AND / OR / NOT
Most real filters are multi-part: paid orders from this quarter, customers in these three countries but not trial accounts, etc.AND, OR, and NOT are how you combine conditions. Most filtering bugs come from boolean logic mistakes, not from syntax, so it is worth slowing down here.
The Three Connectors #
AND: every condition must be true. AddingANDmakes the result narrower.OR: at least one condition must be true. AddingORmakes the result wider.NOTflips a condition.NOT conditionis true whenconditionis false.
-- AND: paid orders over 100
SELECT id, status, total
FROM orders
WHERE status = 'paid' AND total > 100;
-- OR: any order that is paid or pending
SELECT id, status, total
FROM orders
WHERE status = 'paid' OR status = 'pending';
-- NOT: anything that is not cancelled
SELECT id, status, total
FROM orders
WHERE NOT status = 'cancelled';Precedence: AND Binds Tighter Than OR #
When you mix AND and OR, AND is evaluated first.
That rule is the single biggest source of silent filtering bugs.
-- Looks like: "paid or pending, with total > 100"
-- Actually means: "paid, OR (pending AND total > 100)"
WHERE status = 'paid'
OR status = 'pending' AND total > 100;
-- Write what you mean with explicit parentheses:
WHERE (status = 'paid' OR status = 'pending')
AND total > 100;When you mix AND and OR, always use parentheses.
It costs two characters, removes all ambiguity, and protects your query from silently returning the wrong rows when someone edits it six months from now.
Try It #
Run the query below. Then remove the parentheses around (status = 'paid' OR status = 'pending') and compare the row counts.
Practice #
Return id, status, and total for orders that are either paid with a total strictly greater than 100, or pending (any total). No ordering requirement.
Mistakes to Watch For #
- Relying on
AND/ORprecedence without parentheses. NOTwith a nullable column:NOT col = 'x'isUNKNOWNwhencolisNULL, so those rows silently drop. Usecol IS DISTINCT FROM 'x'or handle NULLs explicitly.- Writing
ORchains whenINwould be clearer (covered in the next lesson). - Thinking
!=and<>differ. They are the same operator in every major dialect.
Knowledge check #
4 questions
Without parentheses,
WHERE region = 'EU' OR region = 'US' AND status = 'paid'is equivalent to:WHERE NOT (status = 'cancelled' OR status = 'refunded')is equivalent to (by De Morgan's laws):WHERE col NOT IN (1, 2, NULL)returns:Which two operators always mean the same thing in standard SQL?
Next Step #
Continue to IN / BETWEEN to express multi-value and range filters without stacking ORs.