Contenido de esta guía
Qué conserva LEFT JOIN
LEFT JOIN devuelve todas las filas de la tabla escrita a la izquierda. Cuando encuentra coincidencias en la tabla derecha, combina sus columnas; cuando no encuentra ninguna, coloca NULL en las columnas de la derecha.
Es útil cuando la ausencia también es información: clientes sin pedidos, productos sin ventas o categorías sin artículos.
Sintaxis básica
SELECT izquierda.columnas, derecha.columnas
FROM tabla_izquierda AS izquierda
LEFT JOIN tabla_derecha AS derecha
ON derecha.clave = izquierda.clave;La condición ON explica cómo se relacionan las tablas. La posición importa: intercambiar las tablas cambia qué conjunto de filas se conserva por completo.
Ejemplo guiado
SELECT c.id, c.nombre, p.id AS pedido_id, p.estado
FROM clientes AS c
LEFT JOIN pedidos AS p
ON p.cliente_id = c.id
WHERE c.id IN (1, 6)
ORDER BY c.id, p.id;| id | nombre | pedido_id | estado |
|---|---|---|---|
| 1 | Ana Torres | 101 | enviado |
| 1 | Ana Torres | 103 | cancelado |
| 1 | Ana Torres | 111 | pendiente |
| 6 | Pablo Sanz | NULL | NULL |
Ana aparece una vez por cada pedido coincidente. Pablo aparece aunque no tenga pedidos, y las columnas procedentes de pedidos contienen NULL.
Para buscar filas sin coincidencia, añade WHERE p.id IS NULL. Esa condición selecciona precisamente las filas creadas por el LEFT JOIN cuando no encontró una pareja.
Error frecuente
Filtrar la tabla derecha en WHERE
Esta consulta elimina a los clientes sin pedidos porque p.estado = 'enviado' no es verdadero cuando p.estado vale NULL:
FROM clientes AS c
LEFT JOIN pedidos AS p ON p.cliente_id = c.id
WHERE p.estado = 'enviado'Si quieres conservar a todos los clientes y unir solo sus pedidos enviados, coloca el filtro en ON: ON p.cliente_id = c.id AND p.estado = 'enviado'.
Comprueba lo aprendido
Cuenta pedidos por cliente
Muestra el nombre de todos los clientes y cuántos pedidos tiene cada uno. Los clientes sin pedidos deben aparecer con el valor 0.
clientes.COUNT(p.id), no COUNT(*).Solución razonada
SELECT c.id, c.nombre, COUNT(p.id) AS total_pedidos
FROM clientes AS c
LEFT JOIN pedidos AS p
ON p.cliente_id = c.id
GROUP BY c.id, c.nombre
ORDER BY c.id;COUNT(p.id) ignora el NULL de la fila sin coincidencia y devuelve 0. COUNT(*) contaría esa fila exterior y produciría 1.
Compatibilidad entre motores
La sintaxis LEFT JOIN o LEFT OUTER JOIN está disponible en los principales motores y ambas formas significan lo mismo. Las diferencias prácticas suelen estar en funciones auxiliares, tipos y planes de ejecución, no en la regla básica de conservación de filas.
Qué debes recordar
- La tabla izquierda conserva todas sus filas.
- Las columnas derechas reciben
NULLcuando no hay coincidencia. - Un filtro sobre la tabla derecha puede cambiar el comportamiento si se coloca en
WHERE. - Una relación uno a muchos puede producir varias filas por elemento izquierdo.