Filtering rows with WHERE
Choosing columns narrows a result from side to side. WHERE narrows it from top to bottom. It keeps only the rows that pass a test. This is the most used part of SQL, because a question about data is almost always a question about some of the rows.
The shape of WHERE
WHERE comes after FROM. It is followed by a condition. The database checks the condition for every row and returns the rows where it is true.
SELECT name, city
FROM customers
WHERE city = 'Delhi';Result
| name | city |
|---|---|
| Ravi Kumar | Delhi |
| Imran Ali | Delhi |
2 rows
Only the customers from Delhi are returned. The other rows are still in the table. A SELECT never removes anything.
Comparison operators
| Operator | Meaning |
|---|---|
= | equal to |
<> | not equal to |
< | less than |
> | greater than |
<= | less than or equal to |
>= | greater than or equal to |
Most databases also accept != for "not equal". <> is the standard form.
Comparing numbers
Numbers are written without quotation marks.
SELECT name, price
FROM products
WHERE price > 500;Result
| name | price |
|---|---|
| Basmati Rice 5 kg | 650 |
| School Bag | 750 |
| Power Bank | 1299 |
| Pressure Cooker 3 L | 1450 |
| Bedsheet Double | 899 |
5 rows
The second query finds the products that are sold out.
Comparing text
Text goes in single quotation marks.
SELECT name, category, price
FROM products
WHERE category = 'Stationery';Result
| name | category | price |
|---|---|---|
| Notebook 200 pages | Stationery | 60 |
| Ball Pen pack of 10 | Stationery | 90 |
| Geometry Box | Stationery | 120 |
| School Bag | Stationery | 750 |
4 rows
Leaving the quotation marks out is the most common mistake in this lesson. Without them, the database thinks Stationery is the name of a column.
SELECT name FROM products WHERE category = Stationery;What the database says
Error: no such column: StationeryIs text case sensitive?
It depends on the database, and this surprises people who move from one to another. In SQLite, PostgreSQL and Oracle, 'delhi' does not equal 'Delhi'. In MySQL and SQL Server, with their usual settings, it does.
No rows came back, because in the table the city is written with a capital D. The lesson on functions shows how to compare without caring about case.
Not equal
SELECT id, order_date, status
FROM orders
WHERE status <> 'delivered';Result
| id | order_date | status |
|---|---|---|
| 3 | 2026-01-20 | cancelled |
| 9 | 2026-03-22 | cancelled |
| 13 | 2026-05-19 | shipped |
| 17 | 2026-08-11 | shipped |
| 18 | 2026-09-01 | pending |
| 19 | 2026-09-17 | pending |
| 20 | 2026-10-04 | pending |
7 rows
Comparing dates
In our database, dates are stored as text in the form year, month, day: '2026-03-15'. Written this way, dates sort correctly, and the comparison operators work on them just as you would hope.
SELECT id, order_date, status
FROM orders
WHERE order_date >= '2026-07-01';Result
| id | order_date | status |
|---|---|---|
| 16 | 2026-07-09 | delivered |
| 17 | 2026-08-11 | shipped |
| 18 | 2026-09-01 | pending |
| 19 | 2026-09-17 | pending |
| 20 | 2026-10-04 | pending |
5 rows
Always write dates in year-month-day order with four digits for the year and two each for month and day. Every database understands that form. There is a whole lesson on dates later.
A calculation in the condition
The condition can contain a sum.
SELECT name, price, stock
FROM products
WHERE price * stock > 20000;Result
| name | price | stock |
|---|---|---|
| Basmati Rice 5 kg | 650 | 40 |
| LED Bulb 9 W | 110 | 200 |
| Power Bank | 1299 | 18 |
| Steel Bottle 1 L | 450 | 55 |
| Bedsheet Double | 899 | 25 |
5 rows
You can filter on a column you do not show
The column in the WHERE does not have to be in the SELECT list.
SELECT name
FROM employees
WHERE salary >= 48000;Result
| name |
|---|
| Anita Kapoor |
| Rohit Bansal |
| Deepa Iyer |
| Manoj Yadav |
4 rows
An alias cannot be used in WHERE
This catches everyone once.
SELECT name, price * stock AS stock_value
FROM products
WHERE stock_value > 20000;Some databases, SQLite among them, are forgiving and accept this, so the practice box may run it. Standard SQL does not, and MySQL, PostgreSQL, SQL Server and Oracle refuse. The reason is the order in which a query is carried out: the database filters the rows first and names the columns afterwards, so at the time of the WHERE, the alias does not exist yet. Repeat the calculation in the WHERE, as in the example before this one.
The order of the parts
The parts of a query must come in a fixed order. So far: SELECT, then FROM, then WHERE. Putting WHERE before FROM is an error.
Try it yourself
Exercise 1. Show the name and city of the customers who live in Mumbai.
Show one answer
SELECT name, city FROM customers WHERE city = 'Mumbai';| name | city |
|---|---|
| Kabir Khan | Mumbai |
| Joy Thomas | Mumbai |
2 rows
Exercise 2. Show the name and price of the products that cost 150 rupees or less.
Show one answer
SELECT name, price FROM products WHERE price <= 150;| name | price |
|---|---|
| Sunflower Oil 1 L | 145 |
| Notebook 200 pages | 60 |
| Ball Pen pack of 10 | 90 |
| Geometry Box | 120 |
| LED Bulb 9 W | 110 |
5 rows
Exercise 3. Show the id and date of the orders that were cancelled.
Show one answer
SELECT id, order_date FROM orders WHERE status = 'cancelled';| id | order_date |
|---|---|
| 3 | 2026-01-20 |
| 9 | 2026-03-22 |
2 rows
Examples on this page were run with SQLite 3.50.4 on 12 November 2026. The results shown are the real results.
This is an independent learning site. It is not connected with the makers of any database product. MySQL, PostgreSQL, SQL Server, Oracle and SQLite are named only so that you know where a piece of SQL works. The shop, its customers and its staff in the practice database are made up.