4.1 JOIN¶
Por qué hacen falta los JOIN¶
La tabla alumnos solo guarda el número del grupo, no su nombre:
SELECT nombre, apellido, id_grupo FROM alumnos;
Resultado:
| nombre | apellido | id_grupo |
|---|---|---|
| Ana | Gil | 1 |
| Luis | Romero | 1 |
| Marta | Díaz | 1 |
| Pablo | Núñez | 2 |
| … | … | … |
14 filas (se muestran 4)
Para ver «Ana Gil — 1DAM-A» hay que unir alumnos con grupos, relacionando la clave foránea (alumnos.id_grupo) con la clave primaria (grupos.id).
INNER JOIN¶
SELECT columnas
FROM tabla1
JOIN tabla2 ON condición_de_unión;
SELECT alumnos.nombre, alumnos.apellido, grupos.nombre AS grupo
FROM alumnos
JOIN grupos ON grupos.id = alumnos.id_grupo;
Resultado:
| nombre | apellido | grupo |
|---|---|---|
| Ana | Gil | 1DAM-A |
| Luis | Romero | 1DAM-A |
| Marta | Díaz | 1DAM-A |
| Pablo | Núñez | 1DAM-B |
| Sara | Vega | 1DAM-B |
| Iván | Torres | 1DAM-B |
| Elena | Marín | 2DAM-A |
| Raúl | Campos | 2DAM-A |
| Noa | Prieto | 2DAM-A |
| Dani | Soto | 1DAM-A |
| … | … | … |
13 filas (se muestran 10)
Qué ha hecho el motor: para cada alumno, ha buscado en grupos la fila cuyo id coincide con su id_grupo y ha pegado las dos filas en una.
Dos detalles importantes:
JOINsolo devuelve las filas que tienen pareja (por eso se llama también inner join, unión interna). Irene Lara, que no tiene grupo, no aparece: salen 13 filas, no 14. Si no quieres perderla, se usaLEFT JOIN(siguiente apartado).- Cuando dos tablas tienen una columna con el mismo nombre (
nombreestá en las dos) hay que calificarla con el nombre de la tabla:alumnos.nombre,grupos.nombre.
Alias de tabla¶
Escribir los nombres completos cansa. Se les puede poner un alias corto:
SELECT a.nombre, a.apellido, g.nombre AS grupo, g.curso
FROM alumnos a
JOIN grupos g ON g.id = a.id_grupo
WHERE g.curso = 2
ORDER BY a.apellido;
Resultado:
| nombre | apellido | grupo | curso |
|---|---|---|---|
| Raúl | Campos | 2DAM-A | 2 |
| Elena | Marín | 2DAM-A | 2 |
| Marcos | Peña | 2DAM-A | 2 |
| Noa | Prieto | 2DAM-A | 2 |
4 filas
Con alias, a.nombre es el nombre del alumno y g.nombre el del grupo. El WHERE y el ORDER BY funcionan igual que en las consultas de una tabla.
Las columnas ambiguas dan error
Si una columna existe en las dos tablas y no la calificas, el motor no sabe a cuál te refieres:
SELECT id, nombre FROM alumnos a JOIN grupos g ON g.id = a.id_grupo;
Resultado: error
OperationalError: ambiguous column name: id
Unir tres o más tablas¶
Se encadenan más JOIN. Para ver qué nota tiene cada alumno en cada asignatura, hay que pasar por la tabla intermedia notas:
SELECT a.nombre, a.apellido, s.nombre AS asignatura, n.nota
FROM notas n
JOIN alumnos a ON a.id = n.id_alumno
JOIN asignaturas s ON s.id = n.id_asignatura
WHERE n.convocatoria = 1
ORDER BY n.nota DESC;
Resultado:
| nombre | apellido | asignatura | nota |
|---|---|---|---|
| Iván | Torres | Entornos de Desarrollo | 10.0 |
| Sara | Vega | Lenguajes de Marcas | 9.5 |
| Iván | Torres | Programación | 9.5 |
| Marcos | Peña | Sistemas Informáticos | 9.5 |
| Ana | Gil | Entornos de Desarrollo | 9.0 |
| Raúl | Campos | Bases de Datos | 9.0 |
| Lola | Ortiz | Lenguajes de Marcas | 9.0 |
| Pablo | Núñez | Lenguajes de Marcas | 8.5 |
| … | … | … | … |
46 filas (se muestran 8)
Se lee de arriba a abajo: se parte de notas, se le añade el alumno de cada nota, y después la asignatura. Cada JOIN tiene su propia condición ON.
Cómo plantear un JOIN
- Decide qué quieres ver (columnas) y qué tablas las contienen.
- Busca el camino de claves foráneas que une esas tablas.
- Escribe un
JOIN ... ON clave_foranea = clave_primariapor cada salto. - Añade
WHEREyORDER BYal final.
¿Y si me olvido del ON?¶
Sin condición de unión, el motor combina cada fila de una tabla con cada fila de la otra: es el producto cartesiano. Con 14 alumnos y 3 grupos, salen 14 × 3 filas, casi todas absurdas:
SELECT COUNT(*) AS filas FROM alumnos CROSS JOIN grupos;
Resultado:
| filas |
|---|
| 42 |
1 fila
Si una consulta devuelve muchísimas más filas de las esperadas, casi seguro falta o está mal una condición ON. Existe una sintaxis antigua que une tablas con comas y las condiciones en el WHERE (FROM alumnos a, grupos g WHERE g.id = a.id_grupo); funciona, pero es fácil olvidar la condición, así que se recomienda el JOIN ... ON explícito.
Errores frecuentes¶
| Error | Cómo evitarlo |
|---|---|
| Faltan filas en el resultado | JOIN descarta las que no tienen pareja: ¿necesitas LEFT JOIN? |
| Salen demasiadas filas | Falta la condición ON, o es incorrecta |
ambiguous column name |
Califica la columna con el alias de su tabla |
Unir por la columna equivocada (a.id = g.id) |
Une clave foránea con clave primaria: a.id_grupo = g.id |
| Mezclar la condición de unión con los filtros | La unión va en ON; los filtros, en WHERE |
Para practicar¶
Los ejercicios S4.1 a S4.4 de S4 · Ejercicios practican JOIN.