Skip to content
AgileLogics
4 min read

Combining Conditions: AND, OR, NOT

Prerequisites: Filtering rows with WHERE

Combine conditions with AND, OR, and NOT.

SELECT name, category, price
FROM products
WHERE category = 'Accessories' AND price < 50;
+--------------+-------------+-------+
|     name     |  category   | price |
+--------------+-------------+-------+
| USB-C Hub    | Accessories |  35.5 |
| Laptop Stand | Accessories |    42 |
+--------------+-------------+-------+
  • AND — both conditions must be true.
  • OR — at least one must be true.
  • NOT — reverses a condition.
SELECT id, status
FROM orders
WHERE status = 'pending' OR status = 'shipped';
+----+---------+
| id | status  |
+----+---------+
|  3 | shipped |
|  6 | pending |
|  7 | shipped |
|  8 | pending |
+----+---------+

Use parentheses with mixed AND and OR

AND is evaluated before OR, just as multiplication comes before addition. That can give surprising results:

SELECT name, category, price
FROM products
WHERE category = 'Accessories' OR category = 'Displays' AND price > 100;
+---------------------+-------------+--------+
|        name         |  category   | price  |
+---------------------+-------------+--------+
| Mechanical Keyboard | Accessories |     89 |
| USB-C Hub           | Accessories |   35.5 |
| 27-inch Monitor     | Displays    | 249.99 |
| Laptop Stand        | Accessories |     42 |
+---------------------+-------------+--------+

This means Accessories OR (Displays AND price > 100), so every accessory appears — even the cheap ones — when the intent was probably "accessories or displays costing over 100". Parentheses make the intent explicit:

SELECT name, category, price
FROM products
WHERE (category = 'Accessories' OR category = 'Displays') AND price > 100;
+-----------------+----------+--------+
|      name       | category | price  |
+-----------------+----------+--------+
| 27-inch Monitor | Displays | 249.99 |
+-----------------+----------+--------+

Always use parentheses when a condition mixes AND and OR.

NOT

SELECT id, status
FROM orders
WHERE NOT status = 'delivered';
+----+-----------+
| id |  status   |
+----+-----------+
|  3 | shipped   |
|  5 | cancelled |
|  6 | pending   |
|  7 | shipped   |
|  8 | pending   |
+----+-----------+

Practice

Find customers who live in London or joined in 2025.

Show solution
SELECT name, city, joined_on
FROM customers
WHERE city = 'London' OR joined_on >= '2025-01-01';
+-----------------+--------+------------+
|      name       |  city  | joined_on  |
+-----------------+--------+------------+
| Ada Lovelace    | London | 2024-01-15 |
| Alan Turing     | London | 2024-06-11 |
| Tim Berners-Lee | NULL   | 2025-01-08 |
+-----------------+--------+------------+