INNER JOIN: conservar las coincidencias
Tenemos clientes en una tabla y pedidos en otra. Las dos contienen información distinta sobre la misma operación: una identifica a la persona y la otra registra lo que ocurrió con su pedido.
Si queremos mostrar únicamente los clientes que sí tienen pedidos, necesitamos relacionar ambas tablas y descartar las filas que no encuentran pareja. Ese es el trabajo de INNER JOIN.
La idea
INNER JOIN compara una columna de la primera tabla con una columna de la segunda. La fila aparece en el resultado solo cuando la condición indicada después de ON se cumple.
La relación no tiene que utilizar columnas con el mismo nombre, aunque normalmente se construye mediante una llave primaria y una llave foránea.
Sintaxis
SELECT
tabla_a.Columna,
tabla_b.OtraColumna
FROM TablaA AS tabla_a
INNER JOIN TablaB AS tabla_b
ON tabla_b.IdRelacionado = tabla_a.Id;
Los alias tabla_a y tabla_b permiten indicar con claridad de dónde proviene cada columna. En consultas pequeñas podrían omitirse, pero se vuelven especialmente útiles cuando las tablas comparten nombres como Nombre, Estado o FechaRegistro.
Ejemplo
En la base de ejemplo, Cliente contiene estas filas:
| IdCliente | Nombre |
|---|---|
| 1 | Ana Torres |
| 2 | Bruno Díaz |
| 3 | Carla Ruiz |
| 4 | Diego Soto |
| 5 | Elena Mora |
Pedido contiene:
| IdPedido | IdCliente | FechaPedido | Estado |
|---|---|---|---|
| 1 | 1 | 2026-03-01 10:15 | Confirmado |
| 2 | 1 | 2026-03-04 17:20 | Enviado |
| 3 | 2 | 2026-03-02 12:35 | Pendiente |
| 4 | 4 | 2026-02-15 09:05 | Cancelado |
| 5 | 5 | 2026-03-05 08:50 | Confirmado |
Podemos unirlas mediante IdCliente:
SELECT
c.IdCliente,
c.Nombre,
p.IdPedido,
p.FechaPedido,
p.Estado
FROM dbo.Cliente AS c
INNER JOIN dbo.Pedido AS p
ON p.IdCliente = c.IdCliente
ORDER BY
c.IdCliente,
p.FechaPedido;
Cómo leer el resultado
| IdCliente | Nombre | IdPedido | FechaPedido | Estado |
|---|---|---|---|---|
| 1 | Ana Torres | 1 | 2026-03-01 10:15 | Confirmado |
| 1 | Ana Torres | 2 | 2026-03-04 17:20 | Enviado |
| 2 | Bruno Díaz | 3 | 2026-03-02 12:35 | Pendiente |
| 4 | Diego Soto | 4 | 2026-02-15 09:05 | Cancelado |
| 5 | Elena Mora | 5 | 2026-03-05 08:50 | Confirmado |
Carla no aparece porque no existe un pedido cuyo IdCliente sea 3. Eso no significa que la fila de Carla haya desaparecido de Cliente; únicamente quedó fuera del resultado producido por esta consulta.
Ana aparece dos veces porque tiene dos pedidos. INNER JOIN no produce automáticamente una fila por cliente: produce una fila por cada combinación que cumple la condición de unión.
Qué conviene comprobar
Una multiplicación inesperada de filas suele indicar que la relación no era uno a uno. Antes de agregar DISTINCT para ocultarla, conviene revisar si:
- una fila de la primera tabla tiene varios registros relacionados;
- faltó una condición dentro de
ON; - las columnas utilizadas realmente identifican la relación;
- el resultado debía agruparse en lugar de conservar cada coincidencia.
Si también necesitamos mostrar clientes sin pedidos, INNER JOIN ya no representa la pregunta completa. En ese caso utilizaremos LEFT JOIN.
Relacionado con
LEFT,RIGHTyFULL JOIN.COUNT,SUM,AVG,MINyMAX.GROUP BYyHAVING.EXISTSyNOT EXISTS.