Curso de SQL completo: SELECT, JOIN, agregaciones, índices y transacciones (2026)

Los JOINs son la operación más característica de las bases de datos relacionales. Permiten combinar filas de dos o más tablas basándose en una condición entre columnas, normalmente entre una clave foránea y la clave primaria a la que apunta. Sin JOINs, toda la información tendría que guardarse en una sola tabla gigante, duplicando datos y haciendo imposible el mantenimiento.

INNER JOIN es el tipo de JOIN más común: devuelve solo las filas que tienen correspondencia en ambas tablas. Si un cliente no tiene pedidos, no aparece en un INNER JOIN entre clientes y pedidos.

El problema del producto cartesiano

-- Sin condición de JOIN, se obtiene el producto cartesiano:
-- cada fila de clientes se combina con cada fila de pedidos
-- Si hay 4 clientes y 10 pedidos → 40 filas, todas incorrectas
SELECT * FROM clientes, pedidos;   -- ¡NO hagas esto!

INNER JOIN: la sintaxis correcta

-- Sintaxis estándar (SQL-92, recomendada)
SELECT c.nombre, c.email, p.id AS pedido, p.estado, p.total
FROM pedidos p
INNER JOIN clientes c ON c.id = p.id_cliente;

-- La palabra INNER es opcional; JOIN a secas es INNER JOIN
SELECT c.nombre, p.estado, p.total
FROM pedidos p
JOIN clientes c ON c.id = p.id_cliente;

Alias de tabla

Con alias, las consultas son más cortas y legibles. Se definen directamente después del nombre de la tabla:

-- Sin alias (verboso)
SELECT clientes.nombre, pedidos.total FROM pedidos INNER JOIN clientes ON clientes.id = pedidos.id_cliente;

-- Con alias (limpio)
SELECT c.nombre, p.total FROM pedidos p INNER JOIN clientes c ON c.id = p.id_cliente;

JOIN con tres tablas

-- Detalle de líneas de pedido: pedido, cliente, producto
SELECT
    p.id          AS pedido_id,
    c.nombre      AS cliente,
    pr.nombre     AS producto,
    lp.cantidad,
    lp.precio_ud,
    ROUND(lp.cantidad * lp.precio_ud, 2) AS subtotal
FROM lineas_pedido lp
JOIN pedidos   p  ON  p.id = lp.id_pedido
JOIN clientes  c  ON  c.id = p.id_cliente
JOIN productos pr ON pr.id = lp.id_producto
ORDER BY p.id, pr.nombre;

JOIN con cinco tablas: incluir la categoría

SELECT
    p.id          AS pedido_id,
    c.nombre      AS cliente,
    cat.nombre    AS categoria,
    pr.nombre     AS producto,
    lp.cantidad,
    lp.precio_ud
FROM lineas_pedido lp
JOIN pedidos    p   ON   p.id = lp.id_pedido
JOIN clientes   c   ON   c.id = p.id_cliente
JOIN productos  pr  ON  pr.id = lp.id_producto
JOIN categorias cat ON cat.id = pr.id_categoria
ORDER BY p.id;

Filtrar en el JOIN o en el WHERE

-- Estas dos consultas son equivalentes con INNER JOIN:
-- Condición en el WHERE:
SELECT c.nombre, p.total
FROM pedidos p JOIN clientes c ON c.id = p.id_cliente
WHERE p.estado = 'pagado';

-- Condición en el ON:
SELECT c.nombre, p.total
FROM pedidos p JOIN clientes c ON c.id = p.id_cliente AND p.estado = 'pagado';

-- Nota: con LEFT JOIN NO son equivalentes (ver capítulo siguiente)

USING: cuando las columnas tienen el mismo nombre

-- Si la columna de unión se llama igual en ambas tablas, puedes usar USING
-- (En el esquema del curso las FKs tienen nombres diferentes, pero el concepto aplica)
SELECT nombre, email FROM usuarios u JOIN pedidos p USING (id_usuario);

El INNER JOIN solo devuelve filas con correspondencia en ambas tablas. Si necesitas incluir filas sin correspondencia (por ejemplo, clientes que aún no han hecho ningún pedido), usa LEFT JOIN, que se explica en el siguiente capítulo.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP