AND, OR & NOT
Real questions usually involve more than one condition: products in a category and under a price, orders that are pending or shipped. The logical operators AND, OR and NOT combine conditions — and parentheses make sure they combine the way you mean.
AND: all conditions must be true
SELECT name, category, price FROM products WHERE category = 'Electronics' AND price < 50;
| name | category | price |
|---|---|---|
| USB-C Charger | Electronics | 19.99 |
| Smart Plug | Electronics | 14.99 |
OR: at least one must be true
SELECT id, customer_id, status FROM orders WHERE status = 'pending' OR status = 'shipped';
| id | customer_id | status |
|---|---|---|
| 9 | 6 | shipped |
| 11 | 1 | shipped |
| 12 | 9 | pending |
| 13 | 3 | pending |
| 15 | 7 | pending |
NOT: reverses a condition
SELECT name, category FROM products WHERE NOT category = 'Electronics';
| name | category |
|---|---|
| The Patient Gardener | Books |
| Learning SQL Step by Step | Books |
| Night Sky Atlas | Books |
| Ceramic Mug | Home |
| Desk Lamp | Home |
| Linen Throw | Home |
| Jigsaw Puzzle 1000 | Toys |
| Wooden Train Set | Toys |
NOT is most useful with other operators: NOT IN, NOT LIKE, NOT BETWEEN, NOT EXISTS and IS NOT NULL, all covered in later lessons.
Precedence: AND before OR
Just as multiplication happens before addition, AND is evaluated before OR. This query looks like "cheap books or toys" but isn't:
SELECT name, category, price FROM products WHERE category = 'Books' OR category = 'Toys' AND price < 20;
| name | category | price |
|---|---|---|
| The Patient Gardener | Books | 24.9 |
| Learning SQL Step by Step | Books | 32.5 |
| Night Sky Atlas | Books | 45 |
| Jigsaw Puzzle 1000 | Toys | 18 |
It means category = 'Books' OR (category = 'Toys' AND price < 20), so every book appears regardless of price. Parentheses fix it:
SELECT name, category, price FROM products WHERE (category = 'Books' OR category = 'Toys') AND price < 30;
| name | category | price |
|---|---|---|
| The Patient Gardener | Books | 24.9 |
| Jigsaw Puzzle 1000 | Toys | 18 |
WHERE clause mixes AND and OR, add parentheses — even when they aren't strictly needed, they show your intent.Truth tables
| A | B | A AND B | A OR B |
|---|---|---|---|
| true | true | true | true |
| true | false | false | true |
| false | false | false | false |
| true | unknown | unknown | true |
| false | unknown | false | unknown |
SQL has a third truth value, unknown, which appears whenever NULL is compared. WHERE keeps only rows where the condition is true — unknown rows are dropped. Lesson 11 explores what this means in practice.
Several conditions
SELECT first_name, job_title, salary, hire_date FROM employees WHERE department_id = 2 AND salary >= 68000 AND hire_date < '2023-01-01';
| first_name | job_title | salary | hire_date |
|---|---|---|---|
| Mei | Engineering Manager | 98000 | 2016-09-01 |
| Jonas | Senior Developer | 85000 | 2019-02-18 |
| Amara | Developer | 68000 | 2022-05-09 |
Putting each condition on its own line keeps long filters readable.
Try it yourself
Find customers who are in the UK or France and signed up in 2025.