OR
El operador OR combina dos o más condiciones en una cláusula WHERE. A diferencia de AND, con OR basta con que al menos una de las condiciones sea verdadera para que la fila se incluya en el resultado.
Sintaxis
SELECT columnas
FROM tabla
WHERE condicion1
OR condicion2
OR condicion3;Ejemplo básico
Para obtener los pedidos que estén pendientes o en proceso:
SELECT id, fecha_pedido, estado, total
FROM pedidos
WHERE estado = 'pendiente'
OR estado = 'procesando';| id | fecha_pedido | estado | total |
|---|---|---|---|
| 10 | 2025-11-22 08:45:00 | procesando | 599.99 |
| 11 | 2025-11-25 15:10:00 | procesando | 84.97 |
| 12 | 2025-12-01 10:30:00 | procesando | 199.99 |
| 13 | 2025-12-03 14:00:00 | pendiente | 39.99 |
| 14 | 2025-12-05 11:15:00 | pendiente | 79.98 |
| 15 | 2025-12-08 09:30:00 | pendiente | 1549.00 |
| 18 | 2025-12-15 10:00:00 | pendiente | 329.98 |
| 19 | 2025-12-18 14:30:00 | pendiente | 59.99 |
| 22 | 2025-12-28 15:30:00 | procesando | 399.00 |
| 23 | 2026-01-03 10:45:00 | pendiente | 64.98 |
| 24 | 2026-01-05 12:00:00 | pendiente | 29.99 |
Cada pedido aparece si su estado es "pendiente" o si es "procesando". No necesita cumplir ambas condiciones, basta con una.
OR con distintas columnas
Las condiciones unidas por OR no tienen que referirse a la misma columna. Puedes mezclar criterios completamente distintos:
SELECT nombre, precio, stock
FROM productos
WHERE precio > 1500
OR stock > 200;| nombre | precio | stock |
|---|---|---|
| Lenovo ThinkPad X1 | 1549.00 | 18 |
| ASUS ROG Zephyrus | 1899.99 | 12 |
| Cable USB-C a Lightning | 19.99 | 300 |
| Camiseta algodón básica | 24.99 | 500 |
| Banda elástica set x5 | 19.99 | 200 |
Los dos primeros aparecen porque son caros (precio > 1500). Los tres siguientes aparecen porque tienen mucho stock (> 200 unidades). Observa que el cable USB-C cuesta solo 19.99 euros pero tiene 300 unidades, así que cumple la segunda condición.
Múltiples condiciones OR
Cuando necesitas verificar si una columna tiene uno de varios valores posibles, puedes encadenar varios OR:
SELECT nombre, ciudad
FROM clientes
WHERE ciudad = 'Madrid'
OR ciudad = 'Barcelona'
OR ciudad = 'Valencia';| nombre | ciudad |
|---|---|
| María | Madrid |
| Carlos | Barcelona |
| Pedro | Madrid |
| Laura | Barcelona |
| Carmen | Valencia |
| Roberto | Valencia |
Esta consulta funciona perfectamente, pero cuando la lista de valores crece, se vuelve repetitiva. Para estos casos, el operador IN es más conciso: WHERE ciudad IN ('Madrid', 'Barcelona', 'Valencia'). Lo veremos en un artículo posterior.
Tabla de verdad de OR
La tabla de verdad de OR con lógica de tres valores:
| A | B | A OR B |
|---|---|---|
| TRUE | TRUE | TRUE |
| TRUE | FALSE | TRUE |
| TRUE | NULL | TRUE |
| FALSE | FALSE | FALSE |
| FALSE | NULL | NULL |
| NULL | NULL | NULL |
El punto importante es que OR con NULL devuelve NULL (desconocido), a menos que el otro operando sea TRUE. Si al menos un lado es verdadero, el resultado es verdadero independientemente de lo que haya en el otro lado.
Precedencia: AND se evalúa antes que OR
Este es uno de los errores más comunes en SQL. Cuando mezclas AND y OR, MySQL evalúa AND primero. Considera esta consulta que pretende buscar "productos de electrónica baratos o en oferta":
-- Intención: (smartphones o portátiles) con precio < 100
-- Realidad: smartphones O (portátiles baratos)
SELECT nombre, precio, categoria_id
FROM productos
WHERE categoria_id = 6
OR categoria_id = 7
AND precio < 100;MySQL interpreta esto como:
WHERE categoria_id = 6
OR (categoria_id = 7 AND precio < 100)Resultado: todos los smartphones (sin filtro de precio) más los portátiles que cuesten menos de 100 euros (que no hay ninguno). Lo que probablemente querías es:
SELECT nombre, precio, categoria_id
FROM productos
WHERE (categoria_id = 6 OR categoria_id = 7)
AND precio < 100;Empty set (0.00 sec)
No hay smartphones ni portátiles por debajo de 100 euros, que es el resultado correcto para esa pregunta.
Un ejemplo más donde la precedencia sí importa. Buscar pedidos que necesiten atención: los pendientes con más de 1000 euros, o cualquier pedido cancelado:
SELECT id, estado, total
FROM pedidos
WHERE estado = 'cancelado'
OR estado = 'pendiente' AND total > 1000;| id | estado | total |
|---|---|---|
| 15 | pendiente | 1549.00 |
| 16 | cancelado | 699.00 |
| 17 | cancelado | 49.99 |
| 25 | cancelado | 149.99 |
Aquí la precedencia funciona a nuestro favor: MySQL evalúa estado = 'pendiente' AND total > 1000 primero, y después hace OR con estado = 'cancelado'. El resultado es correcto. Pero para que sea legible, es mejor ser explícito:
WHERE estado = 'cancelado'
OR (estado = 'pendiente' AND total > 1000);OR en condiciones de actualización
OR no solo funciona en SELECT. También puedes usarlo en UPDATE y DELETE:
-- Marcar como inactivos los productos sin stock o con precio 0
UPDATE productos
SET activo = FALSE
WHERE stock = 0
OR precio = 0;Este UPDATE afectaría a cualquier producto que no tenga stock o cuyo precio sea 0. En nuestra base de datos de ejemplo no hay productos con estas condiciones, pero es un patrón habitual en aplicaciones reales.
OR vs IN
Cuando todas las condiciones OR comparan la misma columna contra diferentes valores, IN es una alternativa más limpia:
-- Con OR
SELECT nombre, puesto
FROM empleados
WHERE puesto = 'Vendedor'
OR puesto = 'Vendedora'
OR puesto = 'Vendedor Junior'
OR puesto = 'Vendedora Senior';
-- Con IN (equivalente, más legible)
SELECT nombre, puesto
FROM empleados
WHERE puesto IN ('Vendedor', 'Vendedora', 'Vendedor Junior', 'Vendedora Senior');Ambas devuelven el mismo resultado. IN es preferible cuando la lista tiene más de 2-3 valores.
Practica con OR
Usa el editor para combinar condiciones con OR. Prueba a buscar productos de distintas categorías:
En el siguiente artículo veremos el operador NOT, que invierte el resultado de cualquier condición.
Escrito por Eduardo Lázaro
