Aprende SQL · lección gratuita
Hasta ahora consultabas una tabla a la vez, pero los datos reales viven repartidos en varias tablas relacionadas por claves. Un JOIN combina filas de dos o más tablas según una condición de coincidencia. El INNER JOIN es el más común: devuelve solo las filas que tienen pareja en ambas tablas; las que no coinciden simplemente desaparecen del resultado.
INNER JOIN ... ON: empareja filas cuando la condición del ON es verdadera. Lo típico es relacionar una clave foránea con su clave primaria: ON e.departamento_id = d.id.FROM empleados e puedes escribir e.nombre. Imprescindible para acortar y desambiguar columnas que existen en ambas tablas (como id).id, nombre), debes prefijarla con su alias o SQLite no sabrá a cuál te refieres.JOIN = INNER JOIN: la palabra INNER es opcional; escribir solo JOIN significa lo mismo.departamento_id que no existe en departamentos, el INNER JOIN lo excluiría. (En la semilla todos coinciden.)El motor evalúa el FROM ... JOIN ... ON antes que WHERE, GROUP BY y SELECT. Conceptualmente, primero forma el producto de ambas tablas y se queda con los pares que cumplen el ON; después aplica el resto de cláusulas sobre ese conjunto combinado.
Diferencia clave entre ON y WHERE: en un INNER JOIN son intercambiables para filtrar, pero con LEFT JOIN (próxima lección) no lo son. Por buena práctica, pon en ON la condición de emparejamiento y en WHERE los filtros del resultado.
Un error frecuente es olvidar el ON: en SQLite un JOIN sin ON produce un producto cartesiano (todas las combinaciones), casi nunca lo que quieres.
SELECT e.nombre, e.cargo, d.nombre AS departamento FROM empleados e JOIN departamentos d ON e.departamento_id = d.id LIMIT 6
-- Cada empleado junto al nombre y ciudad de su departamento
SELECT e.nombre, e.cargo, d.nombre AS departamento, d.ciudad
FROM empleados e
INNER JOIN departamentos d ON e.departamento_id = d.id
ORDER BY d.nombre, e.nombre;
-- JOIN + filtro + agregación: salario promedio por departamento en Lima
SELECT d.nombre AS departamento, ROUND(AVG(e.salario), 0) AS salario_medio
FROM empleados e
JOIN departamentos d ON e.departamento_id = d.id
WHERE d.ciudad = 'Lima'
GROUP BY d.nombre
ORDER BY salario_medio DESC;
-- Tres tablas: qué cliente y qué vendedor hay detrás de cada pedido
SELECT p.id AS pedido, c.empresa AS cliente, e.nombre AS vendedor, p.estado
FROM pedidos p
JOIN clientes c ON p.cliente_id = c.id
JOIN empleados e ON p.empleado_id = e.id
ORDER BY p.id
LIMIT 10;
💡 Si unJOINdevuelve más filas de las esperadas, suele ser unONincorrecto o una relación uno-a-muchos (un pedido tiene varias líneas). Si devuelve menos, alguna fila no encuentra pareja: ahí necesitarás unLEFT JOIN.
| Cláusula / Forma | Qué hace |
|---|---|
FROM a JOIN b ON a.fk = b.id | Empareja filas de a y b que coincidan |
INNER JOIN | Solo filas con pareja en ambos lados (default de JOIN) |
FROM empleados e | Alias e para abreviar y desambiguar |
e.nombre, d.nombre | Cualifica columnas con el mismo nombre |
JOIN ... JOIN ... | Encadena varias tablas en una consulta |
---
← Agrupación múltiple y orden de ejecuciónConservar filas: LEFT y RIGHT JOIN →