Aprende SQL

Uniendo tablas: Introducción a JOINs

En bases de datos relacionales, la información se distribuye en múltiples tablas. Los JOIN te permiten combinar datos de varias tablas en una sola consulta.

Pero, ¿por qué separar los datos en varias tablas en lugar de tenerlo todo en una sola? Imagina que repites “Rockstar Games” y “Estados Unidos” en cada juego de ese estudio. Si el nombre cambia, tendrías que actualizarlo en decenas de filas. Esto se llama normalización: dividir la información para evitar datos duplicados y mantener la consistencia. Cada tabla almacena una entidad (juegos, desarrolladores…) y se conectan entre sí mediante claves, como developer_id. Así, el nombre del estudio vive en un solo lugar y cualquier cambio se refleja automáticamente en todas las consultas.

INNER JOIN

El INNER JOIN devuelve solo las filas que tienen coincidencias en ambas tablas. Visualmente, es la intersección entre las dos tablas:

A B
INNER JOIN Solo coincidencias

Donde A es la tabla principal (FROM) y B la tabla que unes (JOIN). Solo se devuelven las filas donde ambas tablas coinciden en la condición de unión.

SELECT columnas
FROM tabla1
INNER JOIN tabla2 ON tabla1.columna = tabla2.columna;

La cláusula ON define la condición de unión, es decir, qué columnas relacionan ambas tablas.

Nuestras tablas

Ahora trabajaremos con dos tablas: videogames y developers. Los videojuegos están relacionados con sus desarrolladores a través del campo developer_id.

Nombre de la Tabla: developers
idnamecountryfounded_year
1NintendoJapón1889
2Square EnixJapón1975
3CD Projekt RedPolonia1994
4Mojang StudiosSuecia2009
5Rockstar GamesEstados Unidos1998
6FromSoftwareJapón1986
7ValveEstados Unidos1996
8Naughty DogEstados Unidos1984
9BungieEstados Unidos1991
10Santa Monica StudioEstados Unidos1999
Nombre de la Tabla: videogames
idtitledeveloper_idyearplaytime_hours
1The Legend of Zelda1198620
2Super Mario Bros.1198510
3Final Fantasy VII2199740
4The Witcher 332015100
5Minecraft420119999
6Grand Theft Auto V5201380
7Dark Souls6201160
8Portal 2720118
9Red Dead Redemption 25201870
10The Last of Us8201315
11Halo: Combat Evolved9200110
12God of War10201825

Ejemplo de INNER JOIN

Para ver el título de cada juego junto al nombre de su desarrollador:

SELECT videogames.title, developers.name
FROM videogames
INNER JOIN developers ON videogames.developer_id = developers.id;

Visualmente, lo que ocurre es que cada fila de videogames busca su coincidencia en developers a través de developer_id, y el resultado combina las columnas de ambas tablas:

videogames
title developer_id
Zelda1
Mario1
GTA V5
Portal 27
RDR 25
developers
id name
1Nintendo
5Rockstar
7Valve
Resultado
title name
ZeldaNintendo
MarioNintendo
GTA VRockstar
Portal 2Valve
RDR 2Rockstar

Fíjate cómo Nintendo aparece dos veces en el resultado (porque tiene dos juegos) y Rockstar también. Cada fila del resultado es una combinación única de juego + desarrollador.

Aliases de tabla

Escribir el nombre completo de cada tabla una y otra vez resulta tedioso. En la práctica, se usan aliases (abreviaturas) para las tablas. Basta con colocar una letra o nombre corto después del nombre de la tabla:

SELECT v.title, d.name
FROM videogames v
INNER JOIN developers d ON v.developer_id = d.id;

Aquí v es el alias de videogames y d el de developers. El resultado es exactamente el mismo, pero la consulta es mucho más limpia y fácil de leer. Esta es la convención que se usa en el mundo real y la que verás en la mayoría de proyectos profesionales.

Self JOIN: unir una tabla consigo misma

Un self join es un JOIN donde una tabla se une consigo misma. Se necesitan aliases obligatoriamente para distinguir las dos “copias” de la tabla.

¿Cuándo es útil? Cuando quieres comparar filas de la misma tabla entre sí. Por ejemplo, encontrar pares de juegos del mismo desarrollador:

SELECT v1.title AS juego_1, v2.title AS juego_2, v1.developer_id
FROM videogames v1
INNER JOIN videogames v2
  ON v1.developer_id = v2.developer_id
  AND v1.id < v2.id;

La condición v1.id < v2.id evita duplicados: sin ella, obtendríamos tanto (Zelda, Mario) como (Mario, Zelda), y también cada juego emparejado consigo mismo.

CROSS JOIN: producto cartesiano

Un CROSS JOIN combina cada fila de una tabla con todas las filas de la otra. No necesita condición ON:

SELECT v.title, d.name
FROM videogames v
CROSS JOIN developers d;

Si videogames tiene 12 filas y developers tiene 10, el resultado tendrá 120 filas (12 × 10). Es el producto cartesiano de ambas tablas.

En la práctica se usa poco, pero es útil para generar combinaciones, como crear un calendario cruzando años con meses, o generar todas las combinaciones posibles de dos conjuntos de datos.

Ejercicios