l comando INNER JOIN en SQL se utiliza para combinar filas de dos o más tablas en función de una condición de coincidencia entre ellas.
Es uno de los tipos de JOIN más usados y su objetivo es devolver solo las filas que tienen coincidencias en ambas tablas.
👉 Dicho de otra forma: INNER JOIN devuelve la intersección de dos conjuntos.
Sintaxis básica de INNER JOIN
SELECT columnas
FROM tabla1
INNER JOIN tabla2
ON tabla1.columna = tabla2.columna;
tabla1,tabla2: las tablas que se van a combinar.- ON: condición de unión (generalmente, PRIMARY KEY en una tabla y FOREIGN KEY en la otra).
Ejemplo básico de INNER JOIN
Supongamos estas dos tablas:
clientes
| id | nombre |
|---|---|
| 1 | Ana |
| 2 | Luis |
| 3 | Carla |
pedidos
| id | cliente_id | total |
|---|---|---|
| 101 | 2 | 500 |
| 102 | 3 | 300 |
| 103 | 4 | 200 |
Consulta:
SELECT c.nombre, p.total
FROM clientes c
INNER JOIN pedidos p ON c.id = p.cliente_id;
Resultado:
| nombre | total |
|---|---|
| Luis | 500 |
| Carla | 300 |
👉 El cliente Ana (id=1) no aparece porque no tiene pedidos. El pedido 103 tampoco aparece porque su cliente_id=4 no existe en la tabla clientes.
INNER JOIN con alias
Es común usar alias para abreviar nombres de tablas:
SELECT c.nombre, p.total
FROM clientes AS c
INNER JOIN pedidos AS p
ON c.id = p.cliente_id;
Hace más legible la consulta, sobre todo si hay varios JOIN.
INNER JOIN con múltiples tablas
Podemos unir más de dos tablas en la misma consulta:
SELECT c.nombre, p.id AS pedido, pr.nombre AS producto
FROM clientes c
INNER JOIN pedidos p ON c.id = p.cliente_id
INNER JOIN productos pr ON p.producto_id = pr.id;
👉 Une clientes con pedidos y además pedidos con productos.
INNER JOIN y condiciones adicionales
Además de la relación de claves, se pueden agregar más filtros:
SELECT c.nombre, p.total
FROM clientes c
INNER JOIN pedidos p ON c.id = p.cliente_id
WHERE p.total > 300;
👉 Devuelve clientes con pedidos mayores a 300.
Más sobre cláusulas en la página de WHERE.
INNER JOIN con varias columnas
En algunos casos, la relación se da por más de una columna:
SELECT *
FROM tablaA a
INNER JOIN tablaB b
ON a.col1 = b.col1
AND a.col2 = b.col2;
INNER JOIN vs otros tipos de JOIN
- INNER JOIN → devuelve solo coincidencias (A ∩ B).
- LEFT JOIN → devuelve todas las filas de la izquierda + coincidencias de la derecha.
- RIGHT JOIN → devuelve todas las filas de la derecha + coincidencias de la izquierda.
- FULL OUTER JOIN → devuelve todas las filas de ambas tablas (coincidan o no).
Visualmente:
INNER JOIN = intersección
INNER JOIN y CROSS JOIN: diferencias
INNER JOINnecesita una condiciónON.CROSS JOINgenera el producto cartesiano (todas las combinaciones).
Errores comunes con INNER JOIN
- Olvidar la condición ON
-- ❌ Error: genera producto cartesiano (muchas filas)
SELECT * FROM clientes INNER JOIN pedidos;
- Confundir condiciones de ON y WHERE
-- Esto funciona, pero es menos claro:
SELECT * FROM clientes c, pedidos p
WHERE c.id = p.cliente_id;
👉 Forma antigua (SQL-92). Recomendado usar INNER JOIN ... ON.
- Duplicación de filas
Si las tablas tienen relaciones de 1 a muchos, pueden aparecer filas repetidas. Ejemplo: un cliente con 3 pedidos aparece 3 veces. Esto no es un error, sino un comportamiento esperado. - Unir por la columna equivocada
Si la condición de unión no está bien definida, se devuelven resultados incorrectos.
Buenas prácticas con INNER JOIN
- Usar alias cortos para mayor legibilidad.
- Asegurar que la condición ON use claves primarias/foráneas o columnas indexadas (INDEX).
- Evitar unir tablas innecesarias: cada
JOINextra puede impactar la performance. - Revisar el plan de ejecución con EXPLAIN para verificar que los índices se están usando.
- Si una tabla es muy grande, considerar índices en las columnas de unión.
Ejemplo avanzado: top clientes con INNER JOIN
SELECT c.nombre, SUM(p.total) AS gasto_total
FROM clientes c
INNER JOIN pedidos p ON c.id = p.cliente_id
WHERE p.fecha >= '2025-01-01'
GROUP BY c.nombre
HAVING SUM(p.total) > 1000
ORDER BY gasto_total DESC
LIMIT 10;
👉 Devuelve los 10 clientes que más gastaron en 2025.
INNER JOIN en distintas bases de datos
- MySQL/MariaDB: soporte completo de
INNER JOIN. - PostgreSQL: igual, con optimizaciones para múltiples índices.
- SQL Server: soporta
INNER JOIN, puede usarseJOINa secas (por defecto es INNER). - Oracle: también soporta
INNER JOIN, aunque en versiones antiguas se usaba la sintaxisWHERE a.col = b.col.
Preguntas frecuentes (FAQ)
1. ¿INNER JOIN es lo mismo que JOIN?
Sí. Cuando escribimos solo JOIN, SQL lo interpreta como INNER JOIN.
2. ¿Qué pasa si no hay coincidencias entre las tablas?
No devuelve filas. INNER JOIN solo muestra coincidencias.
3. ¿INNER JOIN afecta el rendimiento?
Sí, especialmente en tablas grandes. Se recomienda tener índices en las columnas de unión.
4. ¿Se pueden unir más de dos tablas?
Sí, se pueden encadenar múltiples INNER JOIN.
5. ¿Qué diferencia hay entre usar ON y WHERE en los joins?
Funcionalmente pueden dar el mismo resultado, pero la sintaxis con JOIN ... ON es más clara, moderna y fácil de mantener.
Conclusión
El INNER JOIN en SQL es uno de los comandos más usados y esenciales para trabajar con bases de datos relacionales.
Permite unir información distribuida en distintas tablas y obtener reportes completos.
Es fundamental entender cómo funciona, cuándo usarlo y cómo optimizarlo con índices para obtener el mejor rendimiento.
Domina uniones más comunes en JOINS (INNER/LEFT/RIGHT/FULL) y repasa términos en el Glosario SQL completo.