So far every query has returned all the rows in a table. Real questions are more specific: which customers are in Tamil Nadu? Which products cost more than ₹200? The SQL WHERE clause answers them by keeping only the rows that match a condition. It builds directly on SQL SELECT.
How SQL WHERE works
WHERE comes after FROM. The database checks the condition against each row, one at a time. If the condition is true, the row goes into the result; if it is false (or unknown, as you will see with NULL), the row is skipped.
SELECT CustomerName, City
FROM Customers
WHERE State = 'Tamil Nadu';Returns 3 rows: Annapoorna Stores (Chennai), Coimbatore Mart (Coimbatore) and Jasmine Mini Mart (Madurai).
The text value 'Tamil Nadu' is in single quotes. Numbers are written without quotes.
Comparison operators
| Operator | Meaning | Example |
|---|---|---|
= | Equal to | Status = 'Delivered' |
<> or != | Not equal to | Country <> 'India' |
> | Greater than | Salary > 60000 |
< | Less than | Price < 100 |
>= | Greater than or equal to | Price >= 200 |
<= | Less than or equal to | Quantity <= 5 |
<> is the standard SQL way to say “not equal”. != works in SQLite, MySQL and SQL Server too, so use whichever you find easier to read – just stay consistent.
SELECT ProductName, Price
FROM Products
WHERE Price >= 200;Returns 5 rows: Filter Coffee Powder, Cow Ghee, Ponni Rice, Wheat Atta and Cardamom.
Comparing text and dates
In SQLite, = on text is case-sensitive: City = 'chennai' finds nothing, because the stored value is 'Chennai'. MySQL behaves differently – its default collations ignore case, so the same query would match. If you need case-insensitive matching in SQLite, compare LOWER(City) = 'chennai', or use LIKE, which you will meet in SQL LIKE and Wildcards.
SQLite has no separate date type. Our sample database stores dates as text in the YYYY-MM-DD format. Because the year comes first, ordinary text comparison puts dates in the right order, so OrderDate >= '2026-03-01' works as expected. MySQL has a real DATE type, but it accepts the same 'YYYY-MM-DD' style, so the query looks the same.
Combining conditions with AND, OR and NOT
AND– both conditions must be true.OR– at least one condition must be true.NOT– reverses a condition, e.g.NOT Status = 'Cancelled'.
You can chain as many conditions as you need. Each extra AND makes the result smaller, because a row has to pass every test. Each extra OR makes it larger, because a row only has to pass one. Keeping this picture in mind helps when a query returns far more or far fewer rows than you expected.
SELECT OrderID, OrderDate, Status
FROM Orders
WHERE OrderDate >= '2026-03-01'
AND Status <> 'Delivered';Returns 3 rows: order 1007 (Shipped), 1009 (Pending) and 1010 (Shipped).
Use brackets when you mix AND and OR
AND is evaluated before OR, just as multiplication comes before addition in maths. This often catches beginners. Suppose you want developers or sales staff who earn more than ₹70,000. Run the query below, then remove the brackets and run it again.
SELECT FirstName, Department, Salary
FROM Employees
WHERE (Department = 'Development' OR Department = 'Sales')
AND Salary > 70000;Returns 2 rows: Rahul (85000) and Nisha (78000). Without the brackets you get 3 rows, because Ajay (62000) slips in.
Without brackets the database reads it as Development OR (Sales AND salary above 70,000), so every developer appears whatever their salary. When a condition mixes AND and OR, always add brackets – even when they are not strictly needed, they make your intention clear.
Missing values: IS NULL
NULL means “no value” or “unknown”. In our data, two overseas customers have no state. NULL is not zero and not an empty string, and it cannot be compared with =. Even NULL = NULL is not true; it is unknown. So WHERE State = NULL always returns no rows. Use IS NULL and IS NOT NULL instead:
SELECT CustomerName, City, Country
FROM Customers
WHERE State IS NULL;Returns 2 rows: Indus Grocers (Dubai, UAE) and Lotus Organics (Singapore).
Watch out: A condition such as State <> 'Kerala' also skips rows where State is NULL, because comparing with an unknown value gives an unknown answer. If you want those rows too, add OR State IS NULL.
WHERE beyond SELECT
The same SQL WHERE clause is used with UPDATE and DELETE to choose which rows to change – you will see this in SQL INSERT, UPDATE and DELETE. Getting comfortable with conditions now will save you from changing the wrong rows later. Next up: sorting the result in SQL ORDER BY and LIMIT.
