Café y Código

3. Cruzando Información: Los JOINs 🔗

¿Por qué necesitamos JOINs?

Si modelaste correctamente tu Base de Datos (en Tercera Forma Normal), tu información estará esparcida en varias tablas. Los clientes en una tabla, los productos en otra, las ventas en otra.

Para hacer un reporte útil, necesitas cruzar esa información. Los JOINs usan las Llaves Primarias y Foráneas para combinar registros entre tablas.

Tipo de JOIN¿Qué devuelve?Caso de uso típico
INNER JOINSolo las filas que coinciden en ambas tablasVentas con su cliente
LEFT JOINTodas las filas de la izquierda + coincidencias de la derechaTodos los clientes, compren o no
RIGHT JOINTodas las filas de la derecha + coincidencias de la izquierdaTodos los productos, vendidos o no
FULL OUTER JOINTodas las filas de ambas tablasAuditoría completa
CROSS JOINProducto cartesiano (todas las combinaciones posibles)Menú de opciones
SELF JOINUna tabla cruzada consigo mismaJerarquías (empleado → jefe)

1. INNER JOIN: Solo las coincidencias

Es el JOIN más común. Devuelve solo las filas donde existe una correspondencia exacta en ambas tablas. Si un cliente nunca hizo un pedido, no aparece.

SQL
1 -- Solo clientes que tienen al menos un pedido
2 SELECT clientes.nombre, pedidos.fecha, pedidos.monto
3 FROM clientes
4 INNER JOIN pedidos ON clientes.id = pedidos.cliente_id;
Resultado: Solo aparecen combinaciones que existen en las dos tablas. Ningún NULL en las columnas del JOIN.

2. LEFT JOIN: Todos los de la izquierda

Devuelve todas las filas de la tabla izquierda. Si no hay coincidencia en la tabla derecha, los campos de esa tabla se rellenan con NULL.

SQL
1 -- Todos los clientes, tengan pedidos o no
2 SELECT clientes.nombre, pedidos.monto
3 FROM clientes
4 LEFT JOIN pedidos ON clientes.id = pedidos.cliente_id;
5
6 -- Truco: filtrar SOLO los que NO tienen pedido
7 SELECT clientes.nombre
8 FROM clientes
9 LEFT JOIN pedidos ON clientes.id = pedidos.cliente_id
10 WHERE pedidos.id IS NULL;

3. RIGHT JOIN: Todos los de la derecha

Igual que LEFT JOIN pero en sentido contrario. Devuelve todas las filas de la tabla derecha, con NULL donde no hay coincidencia en la izquierda.

SQL
1 -- Todos los pedidos, incluso si el cliente fue borrado
2 SELECT clientes.nombre, pedidos.fecha, pedidos.monto
3 FROM clientes
4 RIGHT JOIN pedidos ON clientes.id = pedidos.cliente_id;
Nota: En la práctica, un RIGHT JOIN casi siempre puede reescribirse como un LEFT JOIN intercambiando el orden de las tablas. Elige el que sea más legible.

4. FULL OUTER JOIN: Todo de todos lados

Combina el resultado de LEFT y RIGHT JOIN. Devuelve todas las filas de ambas tablas, poniendo NULL donde no hay coincidencia en el otro lado.

SQL
1 -- Todos los clientes Y todos los pedidos, coincidan o no
2 SELECT clientes.nombre, pedidos.fecha
3 FROM clientes
4 FULL OUTER JOIN pedidos ON clientes.id = pedidos.cliente_id;
5
6 -- MySQL no soporta FULL OUTER JOIN directamente.
7 -- Se puede simular con UNION:
8 SELECT clientes.nombre, pedidos.fecha FROM clientes
9 LEFT JOIN pedidos ON clientes.id = pedidos.cliente_id
10 UNION
11 SELECT clientes.nombre, pedidos.fecha FROM clientes
12 RIGHT JOIN pedidos ON clientes.id = pedidos.cliente_id;

5. CROSS JOIN: Producto Cartesiano

No usa una condición ON. Combina cada fila de la tabla A con cada fila de la tabla B. Si A tiene 3 filas y B tiene 4, el resultado es 3×4 = 12 filas.

SQL
1 -- Todas las combinaciones posibles de Colores y Tallas
2 SELECT colores.nombre AS color, tallas.nombre AS talla
3 FROM colores
4 CROSS JOIN tallas;
5
6 -- Resultado si colores = {Rojo, Azul} y tallas = {S, M, L}:
7 -- Rojo-S, Rojo-M, Rojo-L, Azul-S, Azul-M, Azul-L
⚠️ Cuidado: Con tablas grandes el resultado puede ser millonario. Úsalo solo cuando realmente necesites todas las combinaciones.

6. SELF JOIN: Una tabla consigo misma

No es un keyword especial, sino una técnica. Usas alias para tratar la misma tabla como si fueran dos tablas distintas. Muy útil para relaciones jerárquicas.

SQL
1 -- Tabla: empleados (id, nombre, jefe_id)
2 -- jefe_id apunta al id del mismo empleado que es su jefe
3
4 SELECT e.nombre AS empleado, j.nombre AS jefe
5 FROM empleados AS e
6 INNER JOIN empleados AS j ON e.jefe_id = j.id;
7
8 -- Resultado:
9 -- Ana → Carlos (Ana es subordinada de Carlos)
10 -- Luis → Carlos
11 -- Carlos → NULL (Carlos no tiene jefe = es el CEO)

🎮 Analizando el cruce

Si cruzas una tabla de 10 Alumnos con una de 5 Becas usando LEFT JOIN (desde Alumnos), ¿cuántas filas devuelve la consulta como mínimo?

👁️ Ver respuesta sugerida

10 filas. El LEFT JOIN siempre garantiza todas las filas de la tabla izquierda. Los 5 alumnos sin beca tendrán la columna de monto en NULL.

Ponte a prueba

Ko-fi
Donaciones
Apoyá cafeycodigo con un café en Ko-fi. Colaboradores: insignia, muro y zona exclusiva.