¿Qué es la cláusula WHERE?
Imagina que tienes una biblioteca con miles de libros. Si alguien te preguntara "¿qué libros tenemos?", tendrías que listar todos. Pero si te preguntaran "¿qué libros de ciencia ficción tenemos escritos después del año 2000?", usarías un filtro para mostrar solo los relevantes. En SQL, ese filtro se llama WHERE.
La sintaxis básica es:
SELECT columna1, columna2
FROM nombre_tabla
WHERE condición;La condición es una expresión lógica que cada fila debe cumplir para ser incluida en el resultado. Solo las filas donde la condición sea verdadera (TRUE) aparecerán.
Operadores de comparación
Los operadores de comparación son el corazón de WHERE. Permiten comparar valores y determinar si una fila cumple o no con nuestro criterio.
| Operador | Descripción | Ejemplo |
|---|---|---|
| = | Igual a | ciudad = 'Madrid' |
| <> | Diferente de | estado <> 'inactivo' |
| < | Menor que | edad < 18 |
| > | Mayor que | precio > 100 |
| <= | Menor o igual que | stock <= 10 |
| >= | Mayor o igual que | ventas >= 1000 |
Ejemplos prácticos con operadores
Usando una tabla de ejemplo empleados con columnas: id, nombre, departamento, salario, fecha_contratacion
-- Encontrar empleados del departamento de Ventas
SELECT nombre, salario
FROM empleados
WHERE departamento = 'Ventas';
-- Empleados con salario mayor a 3000
SELECT nombre, departamento
FROM empleados
WHERE salario > 3000;
-- Empleados contratados antes de 2020
SELECT nombre, fecha_contratacion
FROM empleados
WHERE fecha_contratacion < '2020-01-01';Múltiples condiciones: AND y OR
La vida real rara vez tiene condiciones únicas. Usually, necesitas combinar varios criterios. Para esto, SQL ofrece dos operadores lógicos fundamentales:
- AND: Todas las condiciones deben ser verdaderas
- OR: Al menos una condición debe ser verdadera
Uso de AND
-- Empleados de Ventas con salario mayor a 2500
SELECT nombre, departamento, salario
FROM empleados
WHERE departamento = 'Ventas' AND salario > 2500;Uso de OR
-- Empleados del departamento de RRHH o de Marketing
SELECT nombre, departamento
FROM empleados
WHERE departamento = 'RRHH' OR departamento = 'Marketing';Combinando AND y OR
Cuando combines ambos, usa paréntesis para controlar el orden de evaluación:
-- Empleados senior de Ventas (salario > 4000) O cualquier empleado de RRHH
SELECT nombre, departamento, salario
FROM empleados
WHERE (departamento = 'Ventas' AND salario > 4000)
OR departamento = 'RRHH';El operador LIKE: Búsquedas con patrones
¿Y si quieres encontrar todos los clientes cuyos nombres empiezan con "Mar"? ¿O todos los productos que contienen "azul" en su descripción? Para esto existe LIKE con dos comodines fundamentales:
| Comodín | Significado | Ejemplo |
|---|---|---|
| % | Cualquier secuencia de caracteres | 'Mar%' = cualquier texto que empiece con Mar |
| _ | Un solo carácter | 'Jo_n' = Juan, John, Jon |
-- Clientes cuyo nombre empieza con 'Mar'
SELECT nombre, email
FROM clientes
WHERE nombre LIKE 'Mar%';
-- Productos con 'azul' en cualquier posición
SELECT nombre_producto, descripcion
FROM productos
WHERE descripcion LIKE '%azul%';
-- Códigos que sigan el patrón: dos letras, un número, dos letras
SELECT codigo, descripcion
FROM inventario
WHERE codigo LIKE '__1__';El operador IN: Múltiples valores posibles
Cuando necesitas verificar si un valor está en una lista de opciones, IN hace el código más limpio y legible:
-- Empleados de tres departamentos específicos (versión larga con OR)
SELECT nombre, departamento
FROM empleados
WHERE departamento = 'Ventas'
OR departamento = 'Marketing'
OR departamento = 'Comercial';
-- Misma consulta con IN (más elegante)
SELECT nombre, departamento
FROM empleados
WHERE departamento IN ('Ventas', 'Marketing', 'Comercial');IN también acepta subconsultas, lo que permite comparaciones dinámicas:
-- Productos de categorías que tienen más de 100 unidades en stock
SELECT nombre_producto, categoria
FROM productos
WHERE categoria IN (
SELECT categoria
FROM inventario
WHERE cantidad > 100
);El operador BETWEEN: Rangos inclusivos
Para rangos numéricos o de fechas, BETWEEN ofrece una sintaxis elegante:
-- Empleados con salario entre 2000 y 5000 (incluye ambos extremos)
SELECT nombre, salario
FROM empleados
WHERE salario BETWEEN 2000 AND 5000;
-- Pedidos realizados en el primer trimestre de 2024
SELECT numero_pedido, fecha_pedido, total
FROM pedidos
WHERE fecha_pedido BETWEEN '2024-01-01' AND '2024-03-31';
-- Equivale a:
SELECT numero_pedido, fecha_pedido, total
FROM pedidos
WHERE fecha_pedido >= '2024-01-01'
AND fecha_pedido <= '2024-03-31';Manejo de valores nulos: IS NULL
Los valores nulos representan datos desconocidos o faltantes. No deben confundirse con cadenas vacías o ceros. Para verificar si un valor es nulo, se usa IS NULL (nunca = NULL):
-- Clientes sin número de teléfono registrado
SELECT nombre, email, telefono
FROM clientes
WHERE telefono IS NULL;
-- Empleados que SÍ tienen fecha de finalización de contrato
SELECT nombre, fecha_fin_contrato
FROM empleados
WHERE fecha_fin_contrato IS NOT NULL;Negación: NOT
El operador NOT invierte cualquier condición. Es útil para exclude datos no deseados:
-- Todos los productos EXCEPTO los de la categoría Electrónica
SELECT nombre, categoria, precio
FROM productos
WHERE NOT categoria = 'Electrónica';
-- Equivale a:
SELECT nombre, categoria, precio
FROM productos
WHERE categoria <> 'Electrónica';
-- Combinando NOT con otras condiciones
-- Empleados de Ventas que NO ganan más de 5000
SELECT nombre, departamento, salario
FROM empleados
WHERE departamento = 'Ventas'
AND NOT salario > 5000;Orden de evaluación y paréntesis
SQL evalúa las condiciones en un orden específico:
- Primero: Comparaciones (=, <, >, LIKE, IN, BETWEEN)
- Segundo: NOT
- Tercero: AND
- Cuarto: OR
-- Sin paréntesis: SQL evalúa AND primero
-- Esto encuentra: (Marketing con ventas > 1000) O (cualquiera de RRHH)
SELECT nombre, departamento, ventas
FROM empleados
WHERE departamento = 'Marketing' AND ventas > 1000
OR departamento = 'RRHH';
-- Con paréntesis: SQL evalúa el OR primero
-- Esto encuentra: Marketing O RRHH, y además deben tener ventas > 1000
SELECT nombre, departamento, ventas
FROM empleados
WHERE (departamento = 'Marketing' OR departamento = 'RRHH')
AND ventas > 1000;Ver más: Ejemplo completo integrando todoVamos a crear una consulta compleja que combine todo lo aprendido:
-- Encuentra todos los pedidos que cumplan TODOS estos criterios:
-- 1. Sean del año 2023 o posterior
-- 2. El cliente NO sea de la ciudad de 'Lima'
-- 3. El total esté entre 100 y 5000 (inclusive)
-- 4. El estado sea 'Completado' o 'Enviado'
-- 5. El cliente tenga email registrado (no nulo)
SELECT
p.numero_pedido,
p.fecha_pedido,
p.total,
p.estado,
c.nombre AS cliente,
c.ciudad
FROM pedidos p
JOIN clientes c ON p.cliente_id = c.id
WHERE p.fecha_pedido >= '2023-01-01'
AND c.ciudad <> 'Lima'
AND p.total BETWEEN 100 AND 5000
AND p.estado IN ('Completado', 'Enviado')
AND c.email IS NOT NULL
ORDER BY p.fecha_pedido DESC;Buenas prácticas con WHERE
- Especificidad primero: Filtra lo más restrictivo primero para reducir el conjunto de datos temprano.
- Usa índices: Si filtras frecuentemente una columna, asegúrate de que tenga un índice.
- Evita funciones en columnas filtradas: WHERE YEAR(fecha) = 2024 es más lento que WHERE fecha >= '2024-01-01' AND fecha < '2025-01-01'.
- Comenta tu código: Las consultas complejas merecen explicaciones.
Errores frecuentes y cómo evitarlos
| Error | Problema | Solución |
|---|---|---|
| WHERE nombre = Juan | Sin comillas en texto | WHERE nombre = 'Juan' |
| WHERE fecha = NULL | Comparando con NULL | WHERE fecha IS NULL |
| WHERE x > 10 AND y > 5 OR z > 3 | Sin paréntesis claros | WHERE (x > 10 AND y > 5) OR z > 3 |
| WHERE nombre LIKE '%Juan' | Confundiendo posición del % | LIKE '%Juan%' para encontrar en cualquier parte |
"La diferencia entre una consulta que tarda 0.01 segundos y una que tarda 30 segundos a menudo está en cómo escribimos las condiciones WHERE. Un buen filtrado es la base del rendimiento SQL."
¿Cuál de las siguientes consultas devolverá todos los clientes cuyo nombre empiece con "Ana"?
- A) SELECT * FROM clientes WHERE nombre LIKE '%Ana';
- B) SELECT * FROM clientes WHERE nombre LIKE 'Ana%';
- C) SELECT * FROM clientes WHERE nombre = 'Ana%';
- D) SELECT * FROM clientes WHERE nombre LIKE 'Ana_';
¿Qué consulta muestra los productos con precio entre 50 y 200 euros, excluyendo la categoría 'Ofertas'?
- A) WHERE precio >= 50 AND precio <= 200 AND categoria <> 'Ofertas'
- B) WHERE precio BETWEEN 50 AND 200 OR categoria = 'Ofertas'
- C) WHERE NOT precio BETWEEN 50 AND 200 AND categoria = 'Ofertas'
- D) WHERE categoria NOT IN 'Ofertas' AND precio BETWEEN 50 AND 200
Resumen
La cláusula WHERE es tu herramienta principal para filtrar datos en SQL. Dominar sus operadores y combinadores te permitirá:
- Extraer exactamente los datos que necesitas
- Crear consultas eficientes y legibles
- Combinar múltiples condiciones lógicas
- Buscar patrones de texto con LIKE
- Manejar valores nulos correctamente
En la siguiente lección, aprenderemos a ordenar y limitar resultados con ORDER BY y LIMIT, complementando perfectamente tus habilidades de filtrado.