Himanshu SharmaSoftware engineer
Let’s talk

MySQL · Lesson 6 of 50

WHERE: filtering rows

Use the WHERE clause with comparison operators to return only the rows you need, including text, numbers and dates, with verified output on the sample shop.

13 minReading dataUpdated 22 October 2026

Awaiting technical review. This lesson is readable but not yet listed in search engines.

By the end of this lessonFilter rows with WHERE using comparison operators on numbers, text and dates.

Why filtering matters

Almost no real query wants every row. You want the orders from this month, the customers in one country, the products that are low in stock. The WHERE clause expresses that. It sits after FROM and holds a condition. MySQL tests the condition against each row and keeps the rows where it is true.

sql
SELECT name, price FROM products WHERE price > 50;
result
+-----------------------------+--------+
| name                        | price  |
+-----------------------------+--------+
| Mechanical Keyboard         |  89.50 |
| Noise-Cancelling Headphones | 199.99 |
| Standing Desk Mat           |  55.00 |
+-----------------------------+--------+

Three products cost more than 50. Notice that the condition mentions price, a column that is also in the select list, but it does not have to be. You can filter on a column you do not display.

Comparison operators

Operator Meaning Example
= equal country = 'India'
<> or != not equal status <> 'cancelled'
< and <= less than, less than or equal stock < 50
> and >= greater than, greater than or equal price >= 100

A single = is a comparison here. If you come from a programming language, you may reach for ==, which MySQL does not support.

Filtering on text

Text values go in single quotes. Double quotes work in MySQL too, but single quotes are the SQL standard and avoid confusion with identifiers.

sql
SELECT first_name, last_name, city FROM customers WHERE country = 'India';
result
+------------+-----------+-----------+
| first_name | last_name | city      |
+------------+-----------+-----------+
| Asha       | Verma     | Delhi     |
| Farid      | Khan      | Mumbai    |
| Kavya      | Nair      | Bengaluru |
+------------+-----------+-----------+

With MySQL's default collation, text comparisons ignore case and accents, so this finds the same customers:

sql
SELECT first_name, country FROM customers WHERE country = 'india';
result
+------------+---------+
| first_name | country |
+------------+---------+
| Asha       | India   |
| Farid      | India   |
| Kavya      | India   |
+------------+---------+

If the text itself contains a single quote, double it: 'O''Brien'.

sql
SELECT first_name, last_name FROM customers WHERE last_name = 'O''Brien';
result
+------------+-----------+
| first_name | last_name |
+------------+-----------+
| Liam       | O'Brien   |
+------------+-----------+

Filtering on numbers

Numbers are written without quotes. Combine them with the comparison operators:

sql
SELECT name, stock FROM products WHERE stock <= 40;
result
+-----------------------------+-------+
| name                        | stock |
+-----------------------------+-------+
| Noise-Cancelling Headphones |    25 |
| Standing Desk Mat           |    40 |
| Building Blocks Set         |    35 |
| Puzzle 1000 Pieces          |     0 |
+-----------------------------+-------+

The product with zero stock appears here as well, because 0 is less than 40. Decimal values use a dot: price = 24.99.

Filtering on dates

Dates are written as text in YYYY-MM-DD form and compared like numbers. Earlier dates are smaller:

sql
SELECT id, customer_id, order_date, status FROM orders WHERE order_date >= '2024-06-01';
result
+----+-------------+------------+-----------+
| id | customer_id | order_date | status    |
+----+-------------+------------+-----------+
| 16 |           4 | 2024-06-03 | delivered |
| 17 |           8 | 2024-06-10 | cancelled |
| 18 |          10 | 2024-06-25 | delivered |
| 19 |           6 | 2024-07-07 | pending   |
| 20 |           1 | 2024-07-19 | shipped   |
+----+-------------+------------+-----------+
sql
SELECT id, order_date FROM orders WHERE order_date = '2024-02-14';
result
+----+------------+
| id | order_date |
+----+------------+
|  2 | 2024-02-14 |
+----+------------+

Always use this format. Writing '14/02/2024' does not do what you hope and may silently compare as something else.

Filtering by an expression

The condition can contain calculations and functions as well as plain columns:

sql
SELECT name, price, stock, price * stock AS stock_value FROM products WHERE price * stock > 5000;
result
+---------------------+-------+-------+-------------+
| name                | price | stock | stock_value |
+---------------------+-------+-------+-------------+
| Mechanical Keyboard | 89.50 |    60 |     5370.00 |
| SQL Basics Handbook | 29.95 |   200 |     5990.00 |
+---------------------+-------+-------+-------------+

Remember that you cannot use the alias stock_value in WHERE in this way. The WHERE clause is processed before the select list, so the alias does not exist yet. Repeat the expression, as above, or use a subquery (a later lesson).

Where else you will use WHERE

WHERE is not only for SELECT. The same clause decides which rows UPDATE changes and which rows DELETE removes. That is why this lesson matters beyond reading: a wrong condition on a SELECT shows you the wrong rows, but a wrong condition on a DELETE destroys them. A good habit is to write the WHERE as a SELECT first, check the rows, and only then change the statement.

Common mistakes

  • Forgetting quotes around text: WHERE country = India makes MySQL look for a column named India.
  • Quoting numbers: stock = '10' often works because MySQL converts it, but it is sloppy and can slow queries down.
  • Writing == out of habit from other languages. SQL uses a single =.
  • Comparing dates in other formats than YYYY-MM-DD.
  • Using a select-list alias in WHERE, which fails with "Unknown column".

Exercise

Write queries for the sample shop that return: (1) the name and price of products costing 20 or less, (2) the customers who signed up after 1 July 2023, and (3) the orders whose status is not delivered.

Show one possible answer
sql
SELECT name, price FROM products WHERE price <= 20;
SELECT first_name, signup_date FROM customers WHERE signup_date > '2023-07-01';
SELECT id, status FROM orders WHERE status <> 'delivered';
result
+--------------------+-------+
| name               | price |
+--------------------+-------+
| Ceramic Mug Set    | 18.75 |
| Resistance Bands   | 14.99 |
| Water Bottle       | 12.00 |
| Puzzle 1000 Pieces | 19.99 |
+--------------------+-------+
+------------+-------------+
| first_name | signup_date |
+------------+-------------+
| Jack       | 2023-07-14  |
| Kavya      | 2023-08-30  |
| Liam       | 2023-09-12  |
+------------+-------------+
+----+-----------+
| id | status    |
+----+-----------+
|  4 | shipped   |
|  6 | cancelled |
|  8 | shipped   |
|  9 | pending   |
| 12 | shipped   |
| 14 | pending   |
| 17 | cancelled |
| 19 | pending   |
| 20 | shipped   |
+----+-----------+

Key points

  • WHERE keeps only the rows for which its condition is true. Rows where it is false or unknown are dropped.
  • Comparison operators are =, <> (or !=), <, <=, > and >=. A single = means equals, not assign.
  • Text and dates are written in single quotes. Dates use the YYYY-MM-DD format.
  • With the default collation, text comparison ignores upper and lower case.

Check yourself

1. Which operator tests that two values are equal in a MySQL WHERE clause?
2. Which condition returns orders placed on or after 1 June 2024?
3. Two operators mean not equal in MySQL. Which pair?
4. WHERE country = 'india' is run on the sample shop. What happens with the default collation?