AND, OR, NOT, IN and BETWEEN
One condition is often not enough. You want the stationery that costs under 100 rupees, or the customers from Delhi or Mumbai. This lesson joins conditions together and then shows two shortcuts, IN and BETWEEN.
AND: both must be true
SELECT name, category, price
FROM products
WHERE category = 'Stationery' AND price < 100;Result
| name | category | price |
|---|---|---|
| Notebook 200 pages | Stationery | 60 |
| Ball Pen pack of 10 | Stationery | 90 |
2 rows
A row is returned only if it passes both tests. Each AND you add makes the result smaller or leaves it the same.
OR: at least one must be true
SELECT name, city
FROM customers
WHERE city = 'Delhi' OR city = 'Mumbai';Result
| name | city |
|---|---|
| Ravi Kumar | Delhi |
| Kabir Khan | Mumbai |
| Imran Ali | Delhi |
| Joy Thomas | Mumbai |
4 rows
A row is returned if it passes either test. Each OR you add makes the result larger or leaves it the same.
Each side of an OR must be a complete condition. WHERE city = 'Delhi' OR 'Mumbai' is wrong, though it may not give an error. Write the column name again on each side.
NOT: the opposite
NOT turns a condition around.
SELECT name, category
FROM products
WHERE NOT category = 'Grocery';Result
| name | category |
|---|---|
| Notebook 200 pages | Stationery |
| Ball Pen pack of 10 | Stationery |
| Geometry Box | Stationery |
| School Bag | Stationery |
| LED Bulb 9 W | Electronics |
| Extension Board | Electronics |
| Earphones | Electronics |
| Power Bank | Electronics |
| Steel Bottle 1 L | Home |
| Pressure Cooker 3 L | Home |
| Bedsheet Double | Home |
| Wall Clock | Home |
12 rows
This is the same as category <> 'Grocery'. NOT is most useful together with IN, BETWEEN and LIKE, as you will see below.
Mixing AND and OR: use brackets
When a condition has both AND and OR, the database does the AND parts first, the same way multiplication comes before addition in arithmetic. That can give a result you did not intend.
Suppose you want products in Grocery or Home that cost more than 400 rupees.
SELECT name, category, price
FROM products
WHERE category = 'Grocery' OR category = 'Home' AND price > 400;Result
| name | category | price |
|---|---|---|
| Basmati Rice 5 kg | Grocery | 650 |
| Toor Dal 1 kg | Grocery | 160 |
| Sunflower Oil 1 L | Grocery | 145 |
| Tea 500 g | Grocery | 280 |
| Steel Bottle 1 L | Home | 450 |
| Pressure Cooker 3 L | Home | 1450 |
| Bedsheet Double | Home | 899 |
7 rows
Look at the result. Cheap groceries are in it. The database read the condition as "Grocery, or (Home and over 400)". Brackets fix it.
SELECT name, category, price
FROM products
WHERE (category = 'Grocery' OR category = 'Home') AND price > 400;Result
| name | category | price |
|---|---|---|
| Basmati Rice 5 kg | Grocery | 650 |
| Steel Bottle 1 L | Home | 450 |
| Pressure Cooker 3 L | Home | 1450 |
| Bedsheet Double | Home | 899 |
4 rows
Make it a rule: whenever AND and OR appear together, add brackets, even where they are not strictly needed. The reader, and you in a month, will not have to think about it.
IN: one of a list
A chain of OR tests on the same column is long to write. IN does the same with a list.
SELECT name, city
FROM customers
WHERE city IN ('Delhi', 'Mumbai', 'Pune');Result
| name | city |
|---|---|
| Ravi Kumar | Delhi |
| Kabir Khan | Mumbai |
| Arjun Mehta | Pune |
| Imran Ali | Delhi |
| Joy Thomas | Mumbai |
5 rows
It works with numbers too.
SELECT id, customer_id, status
FROM orders
WHERE customer_id IN (1, 2);Result
| id | customer_id | status |
|---|---|---|
| 1 | 1 | delivered |
| 2 | 2 | delivered |
| 4 | 1 | delivered |
| 7 | 2 | delivered |
| 12 | 1 | delivered |
| 16 | 2 | delivered |
| 20 | 1 | pending |
7 rows
NOT IN gives the rows whose value is not in the list.
SELECT name, department
FROM employees
WHERE department NOT IN ('Sales', 'Support');Result
| name | department |
|---|---|
| Anita Kapoor | Management |
| Farah Sheikh | Warehouse |
| Gopal Reddy | Warehouse |
3 rows
BETWEEN: inside a range
BETWEEN tests whether a value lies in a range. Both ends are included.
SELECT name, price
FROM products
WHERE price BETWEEN 100 AND 300;Result
| name | price |
|---|---|
| Toor Dal 1 kg | 160 |
| Sunflower Oil 1 L | 145 |
| Tea 500 g | 280 |
| Geometry Box | 120 |
| LED Bulb 9 W | 110 |
5 rows
This is the same as price >= 100 AND price <= 300. The smaller value must come first. BETWEEN 300 AND 100 returns nothing.
It works well with dates. These are the orders placed in the first three months of 2026.
SELECT id, order_date
FROM orders
WHERE order_date BETWEEN '2026-01-01' AND '2026-03-31';Result
| id | order_date |
|---|---|
| 1 | 2026-01-05 |
| 2 | 2026-01-12 |
| 3 | 2026-01-20 |
| 4 | 2026-02-02 |
| 5 | 2026-02-14 |
| 6 | 2026-02-28 |
| 7 | 2026-03-03 |
| 8 | 2026-03-15 |
| 9 | 2026-03-22 |
9 rows
A warning for later: if a column stores a time of day as well as a date, BETWEEN '2026-01-01' AND '2026-03-31' misses almost all of the last day, because 31 March at 10 in the morning is later than 31 March at midnight. For such columns, write >= '2026-01-01' AND < '2026-04-01'. Our practice database stores plain dates, so BETWEEN is safe here.
NOT BETWEEN gives the rows outside the range.
SELECT name, salary
FROM employees
WHERE salary NOT BETWEEN 35000 AND 60000;Result
| name | salary |
|---|---|
| Anita Kapoor | 95000 |
| Gopal Reddy | 30000 |
| Nikhil Jain | 33000 |
3 rows
Putting it together
Here is a realistic question: which delivered or shipped orders were placed from April to June 2026?
SELECT id, order_date, status
FROM orders
WHERE status IN ('delivered', 'shipped')
AND order_date BETWEEN '2026-04-01' AND '2026-06-30';Result
| id | order_date | status |
|---|---|---|
| 10 | 2026-04-01 | delivered |
| 11 | 2026-04-18 | delivered |
| 12 | 2026-05-06 | delivered |
| 13 | 2026-05-19 | shipped |
| 14 | 2026-06-02 | delivered |
| 15 | 2026-06-21 | delivered |
6 rows
When a condition gets long, put each part on its own line, starting with AND or OR. It reads like a checklist.
Try it yourself
Exercise 1. Show the name, category and price of Electronics products that cost less than 450 rupees.
Show one answer
SELECT name, category, price FROM products WHERE category = 'Electronics' AND price < 450;| name | category | price |
|---|---|---|
| LED Bulb 9 W | Electronics | 110 |
| Extension Board | Electronics | 399 |
2 rows
Exercise 2. Show the name and state of the customers who live in Punjab or Kerala. Use IN.
Show one answer
SELECT name, state FROM customers WHERE state IN ('Punjab', 'Kerala');| name | state |
|---|---|
| Asha Verma | Punjab |
| Meena Gill | Punjab |
| Priya Nair | Kerala |
| Tara Singh | Punjab |
4 rows
Exercise 3. Show the name and stock of the products whose stock is between 20 and 50, both included.
Show one answer
SELECT name, stock FROM products WHERE stock BETWEEN 20 AND 50;| name | stock |
|---|---|
| Basmati Rice 5 kg | 40 |
| Geometry Box | 45 |
| School Bag | 20 |
| Extension Board | 35 |
| Bedsheet Double | 25 |
| Wall Clock | 30 |
6 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.