00:00

MySQL WHERE Clause

Last updated: 5 min read

The WHERE clause filters rows. It contains a condition, and only rows for which the condition is TRUE are returned, updated or deleted. Almost every real query has one, so mastering WHERE is essential.

1. How WHERE Works

syntax.sql
SELECT columns FROM table WHERE condition;
UPDATE table SET ... WHERE condition;
DELETE FROM table WHERE condition;
WHERE tests each row and keeps the TRUE onesRows flow through the WHERE condition city = 'Pune' AND age >= 25. Rows where the condition is TRUE are kept; rows where it is FALSE or NULL are dropped.studentsnamecityageArjunPune27BeenaDelhi31ChiragPune22DeepaPuneNULLEliPune35WHERE city = 'Pune'AND age >= 25TRUE → keptArjun, EliFALSE / NULL → droppedBeena, Chirag, Deepa
Figure 1: only rows for which the condition is TRUE make it into the result. NULL counts as not TRUE.

Table: students (7 rows)

idnamecityagecoursefee_paidjoined
1ArjunPune27Java45000.002025-07-01
2BeenaDelhi31Python38000.002025-08-15
3ChiragPune22Java20000.002025-09-03
4DeepaPuneNULLData Science52000.002025-11-20
5EliPune35Python38000.002026-01-10
6FarhanMumbai24Java0.002026-02-02
7GauriDelhi29Data Science52000.002026-02-18

2. Comparison Operators

OperatorMeaningExample
=equalcity = 'Pune'
<> or !=not equalcourse <> 'Java'
>, <greater / less thanage > 25
>=, <=greater / less or equalfee_paid >= 40000
<=>NULL-safe equalage <=> NULL
query.sql
SELECT name, course, fee_paid FROM students WHERE fee_paid >= 40000;

Result: 3 rows

namecoursefee_paid
ArjunJava45000.00
DeepaData Science52000.00
GauriData Science52000.00
query.sql
SELECT name, city FROM students WHERE city <> 'Pune';

Result: 3 rows

namecity
BeenaDelhi
FarhanMumbai
GauriDelhi

3. Combining Conditions: AND, OR, NOT

query.sql
SELECT name, city, age FROM students WHERE city = 'Pune' AND age >= 25;

Result: 2 rows

namecityage
ArjunPune27
EliPune35
query.sql
SELECT name, course FROM students WHERE course = 'Python' OR city = 'Mumbai';

Result: 3 rows

namecourse
BeenaPython
EliPython
FarhanJava

AND is evaluated before OR, so use parentheses to say what you mean:

query.sql
SELECT name, city, course FROM students
WHERE (city = 'Pune' OR city = 'Delhi') AND course = 'Data Science';

Result: 2 rows

namecitycourse
DeepaPuneData Science
GauriDelhiData Science

Details: AND, OR, NOT, AND with OR.

4. IN, BETWEEN and LIKE

query.sql
SELECT name, course FROM students WHERE course IN ('Java', 'Python');

Result: 5 rows

namecourse
ArjunJava
BeenaPython
ChiragJava
EliPython
FarhanJava
query.sql
SELECT name, age FROM students WHERE age BETWEEN 25 AND 30;

Result: 2 rows

nameage
Arjun27
Gauri29
query.sql
SELECT name FROM students WHERE name LIKE '%a';   -- names ending in 'a'

Result: 2 rows

name
Beena
Deepa

5. NULL in WHERE

Deepa's age is unknown (NULL). A comparison with NULL is never TRUE, so neither of these finds her:

query.sql
SELECT name FROM students WHERE age = NULL;

Result: Empty set (0 rows)

name
No rows
query.sql
SELECT COUNT(*) AS rows_found FROM students WHERE age > 20 OR age <= 20;

Result: 1 row

rows_found
6

Seven students, but only six counted: NULL is neither above nor below 20. Use IS NULL:

query.sql
SELECT name FROM students WHERE age IS NULL;

Result: 1 row

name
Deepa

6. Filtering Dates

query.sql
SELECT name, joined FROM students WHERE joined >= '2026-01-01';

Result: 3 rows

namejoined
Eli2026-01-10
Farhan2026-02-02
Gauri2026-02-18
query.sql
SELECT name, joined FROM students
WHERE joined >= '2025-08-01' AND joined < '2025-12-01';   -- Aug to Nov 2025

Result: 3 rows

namejoined
Beena2025-08-15
Chirag2025-09-03
Deepa2025-11-20
Compare the bare column with date values, as above. Writing WHERE YEAR(joined) = 2026 gives the same rows but stops MySQL using an index on joined.

7. Expressions and Functions in WHERE

query.sql
SELECT name, fee_paid FROM students WHERE fee_paid / 1000 > 45;

Result: 2 rows

namefee_paid
Deepa52000.00
Gauri52000.00
query.sql
SELECT name, city FROM students WHERE UPPER(LEFT(name, 1)) IN ('A', 'E', 'I', 'O', 'U');

Result: 2 rows

namecity
ArjunPune
EliPune

8. Sub-queries in WHERE

query.sql
SELECT name, course, fee_paid
FROM students
WHERE fee_paid > (SELECT AVG(fee_paid) FROM students);

Result: 5 rows

namecoursefee_paid
ArjunJava45000.00
BeenaPython38000.00
DeepaData Science52000.00
EliPython38000.00
GauriData Science52000.00
query.sql
SELECT name, city FROM students
WHERE city IN (SELECT city FROM students GROUP BY city HAVING COUNT(*) >= 2);

Result: 6 rows

namecity
ArjunPune
BeenaDelhi
ChiragPune
DeepaPune
EliPune
GauriDelhi

9. WHERE in UPDATE and DELETE

The same conditions choose which rows change. Preview with SELECT, then run the change:

preview-then-update.sql
SELECT name, fee_paid FROM students WHERE fee_paid = 0;
UPDATE students SET fee_paid = 15000 WHERE fee_paid = 0;
SELECT name, fee_paid FROM students WHERE id = 6;

Preview

namefee_paid
Farhan0.00

After the UPDATE

namefee_paid
Farhan15000.00

10. Making WHERE Fast with Indexes

An index on a filtered column lets MySQL jump straight to matching rows. The condition must use the column directly (a sargable condition):

explain.sql
CREATE INDEX idx_joined ON students (joined);
EXPLAIN SELECT name FROM students WHERE joined >= '2026-01-01';
EXPLAIN SELECT name FROM students WHERE YEAR(joined) = 2026;

Bare column: uses the index (range)

typekeyrowsExtra
rangeidx_joined3Using index condition

Function on the column: full scan (ALL)

typekeyrowsExtra
ALLNULL7Using where

11. Practice Exercises

Exercise 1: Java or Data Science students who paid at least 45,000.
solution.sql
SELECT name, course, fee_paid FROM students
WHERE course IN ('Java', 'Data Science') AND fee_paid >= 45000;

Result: 3 rows

namecoursefee_paid
ArjunJava45000.00
DeepaData Science52000.00
GauriData Science52000.00
Exercise 2: Students not from Pune whose age is known.
solution.sql
SELECT name, city, age FROM students WHERE city <> 'Pune' AND age IS NOT NULL;

Result: 3 rows

namecityage
BeenaDelhi31
FarhanMumbai24
GauriDelhi29

12. Summary

  • WHERE keeps rows whose condition is TRUE; FALSE and NULL rows are dropped.
  • Use comparison operators, AND/OR/NOT (with parentheses), IN, BETWEEN, LIKE and IS NULL.
  • Never test NULL with =; use IS NULL.
  • Keep indexed columns bare in conditions so indexes can be used.
  • The same WHERE works in SELECT, UPDATE and DELETE.