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 lecturaReferenceSQL · 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:

id name
1 Anna
2 Boris
3 Vera
4 Grisha

grades (notas de examen):

id student_id score
10 1 5
11 1 4
12 2 3

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:

name score
Anna 5
Anna 4
Boris 3
Vera NULL
Grisha NULL

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:

name score
Anna 5

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:

name score
Anna 5
Boris NULL
Vera NULL
Grisha NULL

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:

id name signup_date
1 Anna 2024-01-15
2 Boris 2024-02-01
3 Vera 2024-02-20
4 Grisha 2024-03-10

orders:

id user_id amount created_at
50 1 500 2024-02-05
51 1 1500 2024-02-10
52 2 200 2024-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:

name orders_count total_spent
Anna 2 2000
Boris 1 200
Vera 0 0
Grisha 0 0

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