Concepto clave
Imagina que tienes dos listas de Excel: una con clientes y otra con pedidos. Quieres saber qué cliente hizo cada pedido. En SQL, para combinar datos de dos o más tablas, usamos JOIN. Es como emparejar registros de una tabla con los de otra usando una llave común (por ejemplo, el ID del cliente).
El tipo más común es INNER JOIN, que solo devuelve las filas que tienen coincidencia en ambas tablas. Si un cliente no tiene pedidos, no aparece. Si un pedido no tiene cliente, tampoco. Es como la intersección de dos círculos en un diagrama de Venn.
Otros tipos incluyen LEFT JOIN (todo de la tabla izquierda, y solo coincidencias de la derecha), RIGHT JOIN (al revés) y FULL OUTER JOIN (todo de ambas, con nulos donde no hay coincidencia). Para empezar, domina INNER JOIN y LEFT JOIN.
Cómo funciona en la práctica
Supón que tienes dos tablas: clientes y pedidos. clientes tiene id_cliente, nombre. pedidos tiene id_pedido, id_cliente, total. Quieres listar todos los pedidos con el nombre del cliente.
Paso 1: Identifica la columna común: id_cliente.
Paso 2: Escribe el SELECT con las columnas que quieres: pedidos.id_pedido, clientes.nombre, pedidos.total.
Paso 3: Usa INNER JOIN: FROM pedidos INNER JOIN clientes ON pedidos.id_cliente = clientes.id_cliente.
El resultado será una tabla con cada pedido y el nombre del cliente que lo hizo. Si un cliente no tiene pedidos, no aparece.
Código en acción
Aquí tienes un ejemplo completo con datos de muestra:
-- Crear tablas
CREATE TABLE clientes (
id_cliente INT PRIMARY KEY,
nombre VARCHAR(50)
);
CREATE TABLE pedidos (
id_pedido INT PRIMARY KEY,
id_cliente INT,
total DECIMAL(10,2),
FOREIGN KEY (id_cliente) REFERENCES clientes(id_cliente)
);
-- Insertar datos
INSERT INTO clientes VALUES (1, 'Ana'), (2, 'Luis'), (3, 'Carlos');
INSERT INTO pedidos VALUES (101, 1, 150.00), (102, 2, 200.00), (103, 1, 75.00);
-- INNER JOIN: solo pedidos con cliente existente
SELECT pedidos.id_pedido, clientes.nombre, pedidos.total
FROM pedidos
INNER JOIN clientes ON pedidos.id_cliente = clientes.id_cliente;
Resultado:
id_pedido | nombre | total
101 | Ana | 150.00
102 | Luis | 200.00
103 | Ana | 75.00
Nota: Carlos no aparece porque no tiene pedidos.
Errores comunes
- Olvidar la condición ON: Si pones JOIN sin ON, obtienes un producto cartesiano (todas las combinaciones). Siempre especifica ON.
- Confundir INNER JOIN con LEFT JOIN: INNER JOIN excluye filas sin coincidencia; LEFT JOIN las incluye con nulos. Decide según necesites datos de la tabla izquierda aunque no tengan match.
- No usar alias de tabla: Si las columnas tienen el mismo nombre en ambas tablas, debes prefijarlas con el nombre de la tabla o alias. Ejemplo:
c.nombrevsp.nombre. - JOIN en columnas no indexadas: En tablas grandes, JOIN sin índices puede ser lento. Asegúrate de que las columnas de JOIN tengan índices.
- Usar WHERE en lugar de ON para condiciones de JOIN: Aunque a veces funciona, es mejor poner las condiciones de relación en ON y los filtros adicionales en WHERE.
Checklist de dominio
- [ ] Puedo explicar qué es un JOIN y para qué sirve.
- [ ] Distingo entre INNER JOIN, LEFT JOIN, RIGHT JOIN y FULL OUTER JOIN.
- [ ] Escribo una consulta con INNER JOIN usando ON correctamente.
- [ ] Escribo una consulta con LEFT JOIN y entiendo los nulos resultantes.
- [ ] Uso alias de tabla para hacer el código más legible.
- [ ] Identifico y corrijo errores comunes como falta de ON o producto cartesiano.
- [ ] He completado el ejercicio práctico de combinar tablas de clientes y pedidos.
Combina datos de clientes y pedidos
Objetivo: Crear una consulta que muestre todos los clientes (incluso los que no tienen pedidos) junto con el total de sus pedidos. Si un cliente no tiene pedidos, debe aparecer con total NULL.
Entregable: El script SQL completo (CREATE TABLE, INSERT y SELECT) en un archivo .sql o pegado en la respuesta.
Pasos:
- Crea una tabla
clientescon columnas:id_cliente INT PRIMARY KEY,nombre VARCHAR(50). - Crea una tabla
pedidoscon columnas:id_pedido INT PRIMARY KEY,id_cliente INT,total DECIMAL(10,2), y una clave foránea aclientes(id_cliente). - Inserta al menos 3 clientes: Ana, Luis, Carlos. Inserta al menos 2 pedidos para Ana, 1 para Luis, y ninguno para Carlos.
- Escribe un SELECT que use
LEFT JOINpara mostrar:clientes.nombre,SUM(pedidos.total)comototal_gastado. Agrupa porclientes.id_clienteyclientes.nombre. - Ordena los resultados por
total_gastadode mayor a menor (los NULL deben ir al final).
Mini-rúbrica de evaluación:
- (1 punto) Las tablas están creadas correctamente con tipos de datos adecuados.
- (1 punto) Los datos insertados permiten probar clientes con y sin pedidos.
- (2 puntos) La consulta usa LEFT JOIN correctamente e incluye a Carlos con NULL.
- (1 punto) La agregación SUM y el GROUP BY están bien aplicados.
- (1 punto) El ordenamiento coloca los NULL al final (puedes usar
ORDER BY total_gastado DESC NULLS LASTo similar según tu SGBD).
- Recuerda que LEFT JOIN toma todos los registros de la tabla izquierda (clientes) y solo las coincidencias de la derecha (pedidos).
- Para sumar los totales, usa SUM(pedidos.total). Los clientes sin pedidos tendrán NULL, que se puede mostrar como 0 con COALESCE(SUM(pedidos.total), 0).
- El GROUP BY debe incluir todas las columnas no agregadas del SELECT. En este caso, clientes.id_cliente y clientes.nombre.