La cláusula WHERE filtra las filas que devuelve un SELECT, UPDATE o DELETE. Sin WHERE, la operación afecta a todas las filas de la tabla. Entender bien los operadores disponibles y su precedencia es esencial para escribir condiciones correctas y eficientes.
En este capítulo cubrimos los operadores de comparación, los operadores lógicos AND/OR/NOT, BETWEEN, IN, LIKE y el manejo de NULL en condiciones.
Operadores de comparación
-- Igual SELECT * FROM productos WHERE precio = 59.99; -- Distinto (ambas formas son equivalentes) SELECT * FROM pedidos WHERE estado != 'cancelado'; SELECT * FROM pedidos WHERE estado <> 'cancelado'; -- Mayor, menor, mayor o igual, menor o igual SELECT * FROM productos WHERE precio > 30; SELECT * FROM productos WHERE stock <= 50; SELECT * FROM clientes WHERE fecha_alta >= '2024-01-01';
AND, OR y NOT
-- AND: ambas condiciones deben cumplirse SELECT * FROM productos WHERE precio > 20 AND stock > 100; -- OR: basta con que se cumpla una SELECT * FROM pedidos WHERE estado = 'enviado' OR estado = 'pagado'; -- NOT: niega la condición SELECT * FROM clientes WHERE NOT ciudad = 'Madrid'; -- Combinar: AND tiene más prioridad que OR -- Sin paréntesis, esta consulta NO hace lo que parece: SELECT * FROM productos WHERE precio > 50 OR precio < 10 AND stock > 100; -- Se interpreta como: precio > 50 OR (precio < 10 AND stock > 100) -- Usa siempre paréntesis cuando mezclas AND y OR: SELECT * FROM productos WHERE (precio > 50 OR precio < 10) AND stock > 100;
BETWEEN: rangos de valores
-- Equivale a: precio >= 10 AND precio <= 50 (inclusive en ambos extremos) SELECT nombre, precio FROM productos WHERE precio BETWEEN 10 AND 50; -- Funciona también con fechas y cadenas SELECT * FROM clientes WHERE fecha_alta BETWEEN '2023-01-01' AND '2023-12-31'; -- NOT BETWEEN SELECT * FROM productos WHERE precio NOT BETWEEN 10 AND 50;
IN: lista de valores
-- Equivale a: estado = 'pagado' OR estado = 'enviado'
SELECT * FROM pedidos WHERE estado IN ('pagado', 'enviado');
-- NOT IN
SELECT * FROM clientes WHERE ciudad NOT IN ('Madrid', 'Barcelona');
-- Cuidado: NOT IN con NULLs en la lista siempre devuelve vacío
-- Si ciudad puede ser NULL, esto no devuelve filas donde ciudad es NULL:
SELECT * FROM clientes WHERE ciudad NOT IN ('Madrid', NULL);
-- Usa: WHERE ciudad NOT IN ('Madrid') OR ciudad IS NULL
LIKE: búsqueda de patrones
-- % coincide con cero o más caracteres SELECT * FROM productos WHERE nombre LIKE 'Cable%'; -- empieza por "Cable" SELECT * FROM clientes WHERE email LIKE '%@gmail.com'; -- termina en @gmail.com SELECT * FROM productos WHERE nombre LIKE '%USB%'; -- contiene "USB" -- _ coincide con exactamente un carácter SELECT * FROM clientes WHERE ciudad LIKE '_adrid'; -- "Madrid", "Badrid"... -- LIKE no distingue mayúsculas en MySQL con collation _ci (case insensitive) -- En PostgreSQL usa ILIKE para búsqueda case-insensitive -- NOT LIKE SELECT * FROM productos WHERE nombre NOT LIKE '%Bluetooth%';
IS NULL / IS NOT NULL
-- Clientes sin ciudad asignada SELECT nombre, email FROM clientes WHERE ciudad IS NULL; -- Productos asignados a alguna categoría SELECT nombre FROM productos WHERE id_categoria IS NOT NULL;
Combinar condiciones: ejemplo completo
-- Pedidos de clientes de Madrid o Barcelona, pagados o enviados,
-- en el segundo semestre de 2024
SELECT p.id, c.nombre, p.estado, p.fecha
FROM pedidos p
JOIN clientes c ON c.id = p.id_cliente
WHERE c.ciudad IN ('Madrid', 'Barcelona')
AND p.estado IN ('pagado', 'enviado')
AND p.fecha BETWEEN '2024-07-01' AND '2024-12-31 23:59:59'
ORDER BY p.fecha DESC;
