SQLJOINLEFT JOINtutorial

¿Qué es LEFT JOIN en SQL? Guía para principiantes

LEFT JOIN conserva todas las filas de la tabla izquierda; las coincidencias que faltan a la derecha se vuelven NULL. Cubrimos la sintaxis, la diferencia con INNER JOIN, la búsqueda de huérfanos y tres ejercicios.

7 min de lecturaSQL · JOIN · LEFT JOIN · tutorial · beginner

LEFT JOIN (nombre completo LEFT OUTER JOIN) es una unión en la que todas las filas de la tabla izquierda acaban en el resultado. Cuando no hay coincidencia a la derecha, las columnas del lado derecho son NULL.

Compáralo con INNER JOIN: ese descarta las filas sin coincidencia. LEFT JOIN las conserva, solo marca «nada a la derecha».

Analogía. Una profesora reparte exámenes. No todo el mundo entregó el suyo.

  • INNER JOIN — «muéstrame solo los alumnos que entregaron un examen, con su nota».
  • LEFT JOIN — «muéstrame a todos los alumnos; la nota si entregaron, en blanco si no».

Lo segundo es más a menudo lo que necesitas en la vida real — quieres ver quién se está quedando atrás.

Por qué importa LEFT JOIN

Escenarios clásicos:

  1. Una lista más información opcional, aunque falte. Todos los usuarios + cuántos pedidos tienen (incluido 0).
  2. Encontrar huérfanos — filas sin coincidencia. Usuarios sin pedidos. Productos que nadie compró nunca. Publicaciones sin comentarios.
  3. Contar huecos en los datos. Cuántas lecciones no tienen deberes, cuántas publicaciones no tienen comentarios.

INNER JOIN no sirve aquí — descarta las filas «sin hijos» de inmediato.

Sintaxis básica

SELECT columns
FROM table_A         -- izquierda
LEFT JOIN table_B    -- derecha
  ON A.key = B.key;

«Izquierda» es lo que sigue a FROM. «Derecha» es lo que sigue a LEFT JOIN. Recuerda la dirección: LEFT significa que el lado izquierdo se conserva por completo.

OUTER es opcional. LEFT JOIN y LEFT OUTER JOIN son lo mismo.

Ejemplo: un aula

students:

idname
1Anna
2Boris
3Vera
4Grisha

grades (notas de examen):

idstudent_idscore
1015
1114
1223

Consulta: «cada alumno con sus notas, si las hay».

SELECT s.name, g.score
FROM students s
LEFT JOIN grades g ON s.id = g.student_id;

Resultado:

namescore
Anna5
Anna4
Boris3
VeraNULL
GrishaNULL

Qué hay que observar:

  • Los cuatro alumnos aparecen en el resultado. Ese es todo el sentido del LEFT JOIN.
  • Anna tiene dos notas — dos filas.
  • Boris tiene una — una fila.
  • Vera y Grisha no tienen notas → una fila cada uno, con NULL en score.

Si hubiéramos escrito INNER JOIN, solo quedarían Anna (dos filas) y Boris. Vera y Grisha se caerían — justamente las personas que le importan a la profesora.

Encontrar huérfanos — filas sin coincidencia

Truco clásico. Para encontrar los alumnos que no han hecho ningún examen, filtra por IS NULL:

SELECT s.name
FROM students s
LEFT JOIN grades g ON s.id = g.student_id
WHERE g.id IS NULL;

Resultado:

name
Vera
Grisha

Lógica: LEFT JOIN conserva a cada alumno. Los que no tienen notas tienen NULL en g.id. WHERE g.id IS NULL se queda solo con ellos.

Este patrón (LEFT JOIN ... WHERE other.id IS NULL) es la forma estándar de encontrar «sin coincidencia». Se usa por todas partes: usuarios sin pedidos, publicaciones sin comentarios, productos que nadie compró.

No filtres la tabla derecha en WHERE

La trampa. Si quieres solo las notas de 5 y escribes:

SELECT s.name, g.score
FROM students s
LEFT JOIN grades g ON s.id = g.student_id
WHERE g.score = 5;

Resultado:

namescore
Anna5

Vera y Grisha se cayeron. Porque para ellos WHERE g.score = 5 se evalúa como NULL = 5 (no TRUE) y quedan filtrados. El LEFT JOIN se convirtió de hecho en un INNER JOIN.

Si quieres conservar a todos los alumnos pero mostrar la nota solo cuando sea un 5 — la condición va en ON, no en WHERE:

SELECT s.name, g.score
FROM students s
LEFT JOIN grades g ON s.id = g.student_id AND g.score = 5;

Resultado:

namescore
Anna5
BorisNULL
VeraNULL
GrishaNULL

Ahora los cuatro están en el resultado; la nota aparece solo cuando es un 5. Una diferencia sutil pero crítica. Recuerda: las condiciones sobre la tabla derecha → ON; sobre la izquierda → WHERE.

INNER frente a LEFT — visualizado

Imagina dos tablas de un equipo de fútbol: players y goals (goles marcados). No todos los jugadores marcaron.

  • INNER JOIN → solo los jugadores que marcaron al menos una vez.
  • LEFT JOIN de players a goals → todos los jugadores; los que no marcaron tienen NULL en las columnas de goles.
  • LEFT JOIN + WHERE goals.id IS NULL → solo los jugadores que no marcaron en absoluto.

Tres preguntas distintas — tres consultas distintas.

Ejemplo más grande: comercio electrónico

users:

idnamesignup_date
1Anna2024-01-15
2Boris2024-02-01
3Vera2024-02-20
4Grisha2024-03-10

orders:

iduser_idamountcreated_at
5015002024-02-05
51115002024-02-10
5222002024-02-25

Petición de negocio: «¿cuántos pedidos y cuánto gastó en total cada usuario registrado? Incluye a los que aún no han comprado nada».

SELECT
  u.name,
  COUNT(o.id)               AS orders_count,
  COALESCE(SUM(o.amount), 0) AS total_spent
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id, u.name
ORDER BY total_spent DESC;

Resultado:

nameorders_counttotal_spent
Anna22000
Boris1200
Vera00
Grisha00

Puntos clave:

  • Aparecen los 4 usuarios, incluso Vera y Grisha con cero pedidos.
  • COUNT(o.id) devuelve 0 para ellos (NULL no cuenta en COUNT).
  • SUM devolvería NULL para ellos, así que lo envolvemos en COALESCE(..., 0) — convertir NULL en 0 para una salida limpia.

Una consulta de panel de pan de cada día: «actividad por usuario, incluido el cero».

Errores habituales de principiante

1. WHERE sobre la tabla derecha, convirtiendo sin querer LEFT en INNER. El error más común y más traicionero. Los filtros sobre columnas del lado derecho → ON. Los filtros sobre columnas del lado izquierdo → WHERE.

2. Asustarse con los NULL del resultado. No son un problema — son una señal de «sin coincidencia a la derecha». Usa IS NULL, COALESCE, agregaciones que ignoran NULL, y vas bien.

3. Usar LEFT JOIN cuando hace falta INNER. Si el negocio dice «solo los usuarios que TIENEN pedidos» — eso es INNER JOIN. LEFT JOIN aquí da filas de más y puede ralentizar la consulta.

4. Apilar varios LEFT JOIN y perder el hilo. Las cadenas de A LEFT JOIN B LEFT JOIN C son delicadas — cada nueva condición es relativa a lo que ya hay. Para uniones complejas, constrúyelas de forma incremental.

5. RIGHT JOIN en lugar de intercambiar las tablas. RIGHT JOIN existe y hace la imagen reflejada. En la práctica casi nadie lo usa — simplemente intercambia las tablas y quédate con LEFT JOIN. Más fácil de leer.

6. COUNT(*) frente a COUNT(column) después de un LEFT JOIN. COUNT(*) cuenta todas las filas, incluidas aquellas donde el lado derecho es NULL. COUNT(o.id) cuenta solo las coincidencias reales. Con LEFT JOIN estos dan números distintos.

Resumen rápido

  • LEFT JOIN conserva TODAS las filas de la tabla izquierda.
  • Si el lado derecho no tiene coincidencia — sus columnas son NULL.
  • LEFT JOIN ... WHERE other.id IS NULL es la forma estándar de encontrar las filas sin coincidencia.
  • Las condiciones sobre el lado derecho van en ON; sobre el lado izquierdo, en WHERE.
  • OUTER es opcional; LEFT JOIN = LEFT OUTER JOIN.
  • Más común en las tareas del mundo real que INNER, porque normalmente quieres ver la imagen completa, incluidos los ceros.

Pruébalo tú

Sobre users y orders de arriba:

  1. Lista TODOS los usuarios con el número de pedidos que tienen (incluido el cero).
  2. Encuentra los usuarios sin ningún pedido (patrón IS NULL).
  3. Lista TODOS los usuarios con su pedido más reciente (si lo hay). Pista: LEFT JOIN + MAX(created_at) + GROUP BY.

Cuando LEFT JOIN te encaja, se abre toda una clase de problemas que simplemente no se pueden resolver sin él.

Practica con ejercicios reales

Resuelve ejercicios en el entrenador de SQL con corrección instantánea y pistas.

Abrir el entrenador