LEFT JOIN: también las filas sin pareja
En resumen: LEFT JOIN conserva todas las filas de la tabla izquierda, incluso las que no tienen pareja en la tabla derecha, y rellena con NULL las columnas que faltan.
Problema
¿Quién no ha pedido?
Marketing quiere escribir a los clientes que se registraron pero todavía no han pedido nada. En la última lección JOIN devolvió 60 filas, y Teodora y Yavor no estaban entre ellas.
JOIN conserva solo los pares. Una fila sin pareja desaparece sin avisar. Aquí esas son justo las filas que necesitamos.
La idea
LEFT JOIN
Compara las dos consultas. La primera usa JOIN:
La segunda usa LEFT JOIN:
62 filas en lugar de 60. LEFT JOIN conserva todas las filas de la tabla izquierda (la de FROM), aunque no haya pareja en la derecha. Donde no hay pareja, las columnas de la tabla derecha son NULL. Baja hasta el final: Teodora y Yavor están ahí, con NULL en el número y la fecha.
De aquí, los clientes sin pedidos están a un paso:
WHERE o.id IS NULL conserva solo las filas en las que no se encontró ningún pedido. Comprobamos o.id porque la clave primaria de un pedido encontrado nunca está vacía.
Míralo
Una respuesta vacía también es una respuesta
¿Hay productos que nadie ha pedido nunca? El mismo enfoque, con order_items:
Ni una sola fila. Cada uno de los 25 productos se ha pedido al menos una vez. Una tabla sin filas no es un error: la consulta ha respondido «no hay ninguno».
Pruébalo
Las categorías vacías
¿Qué categorías no tienen ningún producto directamente en ellas? Muestra el nombre de la categoría.
Solución
SELECT cat.name
FROM categories cat
LEFT JOIN products p ON p.category_id = cat.id
WHERE p.id IS NULL;FROM categories cat LEFT JOIN products p ON p.category_id = cat.id WHERE p.id IS NULL. «Alimentos» y «Hogar». Son las categorías de arriba: los productos están en sus subcategorías. Con un JOIN normal no salen en absoluto.
Míralo
Contar con los ceros
¿Cuántos pedidos tiene cada cliente, incluidos los que no tienen ninguno? Un primer intento con COUNT(*):
¿Teodora y Yavor tienen 1 pedido cada uno? No. COUNT(*) cuenta filas, y LEFT JOIN le dio a cada uno una fila llena de NULL. Cuenta lo que tiene valor, COUNT(o.id):
COUNT(columna) salta los NULL, así que salen con 0. Con LEFT JOIN, cuenta una columna de la tabla derecha, preferiblemente su clave primaria.
Pruébalo
Reseñas por producto
Muestra cada producto y cuántas reseñas tiene, incluidos los productos sin reseña (con 0).
Solución
SELECT p.name, COUNT(r.id) AS reviews
FROM products p
LEFT JOIN reviews r ON r.product_id = p.id
GROUP BY p.id, p.name;FROM products p LEFT JOIN reviews r ON r.product_id = p.id GROUP BY p.id, p.name con COUNT(r.id). 25 filas. Con COUNT(*) los productos sin reseña mostrarían 1, y con JOIN faltarían.
Míralo
La trampa de WHERE
Un informe de octubre: todos los clientes y cuántos pedidos han hecho desde el 1 de octubre de 2026. La condición de la fecha va en WHERE:
Cinco filas, pero hay 20 clientes. Una condición sobre la tabla derecha en WHERE convierte un LEFT JOIN en un JOIN normal. Su sitio está en ON: allí dice qué pedidos unir, y todos los clientes se quedan.
20 clientes, la mayoría con 0. La regla: con LEFT JOIN, una condición sobre la tabla derecha va en ON. La excepción es IS NULL, cuando buscas los que faltan.
Ejercicio
Dos tareas
1. La tienda invitará a escribir una reseña a los clientes que todavía no han escrito ninguna. ¿Quiénes son? Muestra el nombre.
Los clientes sin una sola reseña:
Solución
SELECT c.name
FROM customers c
LEFT JOIN reviews r ON r.customer_id = c.id
WHERE r.id IS NULL;FROM customers c LEFT JOIN reviews r ON r.customer_id = c.id WHERE r.id IS NULL. Seis: Petya, Martin, Simona, Hristo, Teodora y Yavor.
2. La campaña «Te echamos de menos» es para los clientes que no han hecho ningún pedido desde el 1 de julio de 2026 (incluidos los que nunca han pedido). Muestra el nombre y el correo.
Los clientes sin pedido desde el 2026-07-01:
Solución
SELECT c.name, c.email
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id AND o.ordered_at >= '2026-07-01'
WHERE o.id IS NULL;La fecha va en ON, y IS NULL en WHERE: LEFT JOIN orders o ON o.customer_id = c.id AND o.ordered_at >= '2026-07-01' WHERE o.id IS NULL. 10 clientes. Si la fecha está en WHERE, no sale nadie: las filas con NULL se descartan por la fecha, y las filas con fecha se descartan por IS NULL.
Más precisamente, para curiosos
También existen RIGHT JOIN (conserva las filas de la tabla derecha) y FULL JOIN (conserva ambos lados). SQLite los entiende desde la versión 3.39. RIGHT JOIN se escribe poco: es lo mismo que LEFT JOIN con las tablas intercambiadas. MySQL no tiene FULL JOIN.
Aquí salen solo los clientes sin pedidos, porque cada pedido tiene un cliente.
Test
Ponte a prueba
Lecciones relacionadas
Sección «Lecciones relacionadas»- Se basa en: Funciones de agregación: COUNT, SUM, AVG · GROUP BY: un informe por grupos · Clave primaria y clave foránea · JOIN: dos tablas en una consulta
- Continúa en: Muchas tablas, y una tabla unida consigo misma · UNION, INTERSECT, EXCEPT y CROSS JOIN · Un informe por pasos: WITH · Árboles y secuencias: WITH RECURSIVE
- Ejercicios sobre el tema: Unir tablas