INNER JOIN en SQL: qué es, cómo funciona y ejemplos prácticos

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

idnombre
1Ana
2Luis
3Carla

pedidos

idcliente_idtotal
1012500
1023300
1034200

Consulta:

SELECT c.nombre, p.total
FROM clientes c
INNER JOIN pedidos p ON c.id = p.cliente_id;

Resultado:

nombretotal
Luis500
Carla300

👉 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 JOIN necesita una condición ON.
  • CROSS JOIN genera el producto cartesiano (todas las combinaciones).

Errores comunes con INNER JOIN

  1. Olvidar la condición ON
-- ❌ Error: genera producto cartesiano (muchas filas)
SELECT * FROM clientes INNER JOIN pedidos;
  1. 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.

  1. 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.
  2. 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 JOIN extra 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.

Más sobre GROUP BY y HAVING.

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 usarse JOIN a secas (por defecto es INNER).
  • Oracle: también soporta INNER JOIN, aunque en versiones antiguas se usaba la sintaxis WHERE 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.

Scroll al inicio