Only the rows you need
Problem
What ran out?
Every morning the manager wants to know which products need ordering because they have run out. The table has 25 products. Tomorrow it will have 2,500.
They do not need all the rows. They need only the ones where the stock is 0.
The idea
WHERE
WHERE keeps only the rows for which the condition is true:
The database goes through every row, checks stock = 0 and keeps the true ones. The condition can use any column, not only those in SELECT.
The comparisons are: = equal, <> different, <, >, <=, >=. Numbers are written with a decimal point:
Text goes in single quotes:
More precisely, if you are curious
SQLite also accepts city = "Plovdiv" in double quotes, but only out of an old habit: if there is no column by that name, it takes it as text. PostgreSQL will say there is no column “Plovdiv”. Write text in single quotes and the query will work everywhere.
Try it
The expensive products
Show the name and price of the products that cost at least 10 €.
Solution
SELECT name, price FROM products WHERE price >= 10;WHERE price >= 10. Six products, from the cutting board (11.40 €) to the knife set (39 €). “At least 10” includes 10, so it is >= and not >.
The idea
AND, OR, NOT
Conditions can be combined:
AND: both must be true.OR: at least one is true.NOT: turns the condition around.
Cheap products there are plenty of (for a “take three” offer):
See it
The OR trap
Marketing wants the customers from Sofia or Plovdiv who signed up since the start of 2026. Here is a first attempt. Run it and look at the dates:
With brackets, the condition says exactly what you mean:
Whenever you mix AND and OR, add brackets, even when they are not required. Whoever reads the query after you will not have to wonder.
Try it
The waiting orders
Show the number, customer and status of the orders that are new or paid, but not yet shipped.
Solution
SELECT id, customer_id, status FROM orders WHERE status = 'new' OR status = 'paid';WHERE status = 'new' OR status = 'paid'. 23 orders: 11 new and 12 paid. With AND instead of OR nothing comes out, because an order has one status.
Exercise
Two tasks
1. All orders except the cancelled ones (cancelled). Show the number and status. Try it with NOT.
The orders that are not cancelled:
Solution
SELECT id, status FROM orders WHERE NOT status = 'cancelled';WHERE NOT status = 'cancelled', or shorter, WHERE status <> 'cancelled'. 53 orders.
2. The shop opens a warehouse on the coast. Which customers from Varna or Burgas have been with us since 2025? Show the name, city and sign-up date.
Customers from Varna or Burgas who signed up before 2026:
Solution
SELECT name, city, joined_at FROM customers
WHERE (city = 'Varna' OR city = 'Burgas') AND joined_at < '2026-01-01';WHERE (city = 'Varna' OR city = 'Burgas') AND joined_at < '2026-01-01'. Dates are text in year-month-day form, so < compares them correctly. Without the brackets, Hristo from Varna, who signed up in 2026, would also come out.
Test