SQL INNER JOIN: combinar filas de dos tablas

Con SQL INNER JOIN, obtienes solo las filas donde la condición de unión coincide en ambas tablas. Úsalo para combinar datos relacionados, como vincular registros con sus valores de referencia, cuando las filas sin coincidencia deben excluirse del resultado. Como ambos lados deben cumplir el predicado de unión, cualquier fila con una clave de unión NULL o sin coincidencia correspondiente se filtra automáticamente.

Ejemplo de SQL INNER JOIN para combinar tablas relacionadas

Salida:

La salida aparecerá aquí...

Salida:

+----------+--------------+
| empleado | departamento |
+----------+--------------+
| Alma     | Ingeniería   |
| Ben      | Ingeniería   |
| Cara     | Ventas       |
+----------+--------------+
3 row(s)

Cómo funciona este ejemplo

  1. departments contiene tres departamentos; employees contiene cuatro personas, cada una con una clave foránea dept_id. El dept_id de Dan es NULL.
  2. INNER JOIN departments d ON d.id = e.dept_id empareja cada fila de empleado con la fila de departamento cuyo id es igual al dept_id del empleado. Solo se conservan los pares donde ambos lados coinciden.
  3. Dan tiene dept_id = NULL. El operador = devuelve desconocido cuando cualquiera de los operandos es NULL, así que Dan nunca coincide con ningún departamento y se excluye.
  4. El departamento de RRHH (id 3) no tiene empleados que apunten a él, por lo que tampoco aparece: INNER JOIN descarta filas sin coincidencia de ambos lados.

¿Qué es SQL INNER JOIN?

INNER JOIN produce la intersección de dos tablas según un predicado de unión. En términos lógicos, conserva solo los pares de filas donde la condición ON se evalúa como verdadera. La ejecución física varía según el motor y la forma de los datos (nested loops, hash join, merge join), pero el conjunto de resultados siempre contiene solo filas coincidentes.

INNER JOIN vs LEFT JOIN

INNER JOINLEFT JOIN
Devuelve solo filas coincidentes de ambas tablasDevuelve todas las filas de la tabla izquierda, con NULL donde no existe coincidencia
Las filas sin coincidencia se descartan en silencioLas filas sin coincidencia de la izquierda se conservan con columnas derechas rellenadas con NULL
Úsalo cuando las coincidencias faltantes signifiquen datos inválidosÚsalo cuando necesites ver todos los registros del lado izquierdo, haya o no coincidencias

Regla: elige INNER JOIN cuando cada fila del resultado deba tener datos válidos de ambas tablas. Cambia a LEFT JOIN cuando necesites conservar filas incluso sin coincidencia en la tabla derecha.

Errores comunes con SQL INNER JOIN

Predicado de unión ausente o siempre verdadero

Omitir la cláusula ON (o usar una condición que siempre sea verdadera) produce un producto cartesiano: cada empleado se empareja con cada departamento.

-- Incorrecto: producto cartesiano (12 filas de 4 × 3)
SELECT * FROM employees, departments;

-- Correcto: predicado de unión explícito
SELECT * FROM employees e
INNER JOIN departments d ON d.id = e.dept_id;

Claves de unión no únicas que multiplican filas

INNER JOIN devuelve una fila de salida por cada par coincidente. Si te unes a una tabla donde la clave no es única, una fila de la izquierda puede coincidir con varias filas de la derecha y multiplicar tus resultados.

INNER JOIN vs EXISTS

Usa INNER JOIN cuando necesites columnas de ambas tablas en la salida. Usa EXISTS cuando solo necesites filtrar filas según si hay una fila relacionada. EXISTS también evita la multiplicación de filas si la subconsulta puede coincidir con varias filas, y el planificador de consultas a menudo puede detenerse después de la primera coincidencia.

-- EXISTS: una fila por empleado que tiene un departamento coincidente
SELECT e.name FROM employees e
WHERE EXISTS (SELECT 1 FROM departments d WHERE d.id = e.dept_id);

Notas de rendimiento

Indexa las columnas usadas en el predicado de unión (dept_id y departments.id en este caso). Sin índice, el motor puede escanear la tabla interna muchas veces. Para tablas grandes, verifica el plan con EXPLAIN QUERY PLAN: busca “USING INDEX” o “SEARCH” en lugar de “SCAN”.