MySQL OR Condition
The OR operator combines conditions so that a row is returned if at least one of them is true. Use it for alternatives: hotels in Goa or with a pool, orders that are either cancelled or refunded.
1. Syntax and Meaning
WHERE condition1 OR condition2 [OR condition3 ...]
Table: hotels (7 rows)
| hotel_id | name | city | rating | price | pool | spa |
|---|---|---|---|---|---|---|
| 1 | Sea Breeze | Goa | 4.5 | 6200 | 1 | 0 |
| 2 | Palm Court | Goa | 3.8 | 3900 | 0 | 0 |
| 3 | Hill View | Shimla | 4.2 | 5400 | 0 | 1 |
| 4 | Lagoon Bay | Goa | 4.1 | 8800 | 1 | 1 |
| 5 | City Inn | Jaipur | 3.5 | 2500 | 0 | 0 |
| 6 | Fort Palace | Jaipur | 4.7 | 12000 | 1 | 1 |
| 7 | Snow Peak | Shimla | NULL | 4700 | NULL | 0 |
2. Basic OR
SELECT name, city, pool FROM hotels WHERE city = 'Goa' OR pool = TRUE;
Result: 4 rows
| name | city | pool |
|---|---|---|
| Sea Breeze | Goa | 1 |
| Palm Court | Goa | 0 |
| Lagoon Bay | Goa | 1 |
| Fort Palace | Jaipur | 1 |
3. Several OR Conditions
SELECT name, price, rating FROM hotels WHERE price < 3000 OR rating >= 4.5 OR spa = TRUE;
Result: 5 rows
| name | price | rating |
|---|---|---|
| Sea Breeze | 6200 | 4.5 |
| Hill View | 5400 | 4.2 |
| Lagoon Bay | 8800 | 4.1 |
| City Inn | 2500 | 3.5 |
| Fort Palace | 12000 | 4.7 |
4. OR Truth Table (with NULL)
| A | B | A OR B |
|---|---|---|
| TRUE | anything (even NULL) | TRUE |
| FALSE | FALSE | FALSE |
| FALSE | NULL | NULL |
| NULL | NULL | NULL |
SELECT (1=1) OR NULL AS true_or_null, (1=2) OR NULL AS false_or_null, (1=2) OR (2=3) AS false_or_false;
Result: 1 row
| true_or_null | false_or_null | false_or_false |
|---|---|---|
| 1 | NULL | 0 |
Snow Peak has NULL rating and NULL pool. It is returned only when one condition is definitely TRUE:
SELECT name FROM hotels WHERE rating > 4 OR pool = TRUE;
Snow Peak not included (both NULL)
| name |
|---|
| Sea Breeze |
| Hill View |
| Lagoon Bay |
| Fort Palace |
SELECT name FROM hotels WHERE rating > 4 OR city = 'Shimla';
Snow Peak included (city is TRUE)
| name |
|---|
| Sea Breeze |
| Hill View |
| Lagoon Bay |
| Fort Palace |
| Snow Peak |
5. OR on One Column: Use IN
SELECT name, city FROM hotels WHERE city = 'Goa' OR city = 'Shimla' OR city = 'Ooty';
Result: 5 rows
| name | city |
|---|---|
| Sea Breeze | Goa |
| Palm Court | Goa |
| Hill View | Shimla |
| Lagoon Bay | Goa |
| Snow Peak | Shimla |
SELECT name, city FROM hotels WHERE city IN ('Goa', 'Shimla', 'Ooty');
Result: 5 rows
| name | city |
|---|---|
| Sea Breeze | Goa |
| Palm Court | Goa |
| Hill View | Shimla |
| Lagoon Bay | Goa |
| Snow Peak | Shimla |
Same result; IN is shorter and easier to maintain.
6. Mixing OR with AND
AND binds tighter than OR. Without parentheses, this means city = 'Goa' OR (city = 'Jaipur' AND price < 5000):
SELECT name, city, price FROM hotels WHERE city = 'Goa' OR city = 'Jaipur' AND price < 5000;
Result: 4 rows
| name | city | price |
|---|---|---|
| Sea Breeze | Goa | 6200 |
| Palm Court | Goa | 3900 |
| Lagoon Bay | Goa | 8800 |
| City Inn | Jaipur | 2500 |
SELECT name, city, price FROM hotels WHERE (city = 'Goa' OR city = 'Jaipur') AND price < 5000;
Result: 2 rows
| name | city | price |
|---|---|---|
| Palm Court | Goa | 3900 |
| City Inn | Jaipur | 2500 |
See MySQL AND with OR for more.
7. XOR: Exactly One of Two
MySQL also has XOR: true when exactly one side is true. Hotels with a pool or a spa, but not both:
SELECT name, pool, spa FROM hotels WHERE pool XOR spa;
Result: 2 rows
| name | pool | spa |
|---|---|---|
| Sea Breeze | 1 | 0 |
| Hill View | 0 | 1 |
8. OR in UPDATE
UPDATE hotels SET price = ROUND(price * 0.9)
WHERE rating < 4 OR rating IS NULL;
SELECT name, rating, price FROM hotels WHERE rating < 4 OR rating IS NULL;
Result: 3 rows
| name | rating | price |
|---|---|---|
| Palm Court | 3.8 | 3510 |
| City Inn | 3.5 | 2250 |
| Snow Peak | NULL | 4230 |
9. OR and Indexes
An index on one column can't serve a = 1 OR b = 2 by itself. MySQL may combine two indexes (index merge union) or fall back to a full scan. For large tables, rewriting as UNION of two indexed queries is a classic fix:
SELECT name FROM hotels WHERE city = 'Goa'
UNION
SELECT name FROM hotels WHERE spa = TRUE;
Result: 5 rows
| name |
|---|
| Sea Breeze |
| Palm Court |
| Lagoon Bay |
| Hill View |
| Fort Palace |
10. Practice Exercises
Exercise 1: Hotels that are very cheap (under 3,000) or very expensive (over 10,000).
SELECT name, price FROM hotels WHERE price < 3000 OR price > 10000;
Result: 2 rows
| name | price |
|---|---|
| City Inn | 2250 |
| Fort Palace | 12000 |
Exercise 2: Shimla or Jaipur hotels with a rating of at least 4.
SELECT name, city, rating FROM hotels WHERE (city = 'Shimla' OR city = 'Jaipur') AND rating >= 4;
Result: 2 rows
| name | city | rating |
|---|---|---|
| Hill View | Shimla | 4.2 |
| Fort Palace | Jaipur | 4.7 |
11. Summary
- OR returns rows where at least one condition is TRUE.
- TRUE OR NULL is TRUE; FALSE OR NULL is NULL.
- Use IN for many ORs on one column; use parentheses when mixing OR with AND.
- XOR means exactly one; OR across columns may need index merge or a UNION rewrite.