Cláusula JOIN en SQL

Cláusula JOIN

El modelo relacional nos permite, ejecutar consultas sobre varias tablas relacionadas, de manera que podamos extraer e integrar la información de varias tablas desde una sola ejecución. Esto es posible gracias a la cláusula JOIN, que explicaremos en más detalle a continuación:

Para entender mejor los ejemplos, hemos realizado algunos INSERT INTO nuevos en la tabla Clientes y Pedidos:

INSERT INTO Clientes (nombre, apellidos, direccion, cuenta)
VALUES ('Paloma', 'Sanz Valdivia', 'Av. de la Ilustración 49', 790763467);

INSERT INTO Clientes (nombre, apellidos, direccion, cuenta)
VALUES ('Ignacio', ' Herrero Dominguez', ' C/ del girasol 3', NULL;

INSERT INTO Pedidos (producto, descripcionProducto, precio, fechaPedido, numeroProductos, idClientes)
VALUES ('Horno Balay', 'Electrodoméstico', '699.55', '2022-09-10', 2, NULL);
SELECT * FROM Clientes
WHERE idClientes IN (6, 7);
idClientes nombre apellidos direccion cuenta
6 Paloma Sanz Valdivia Av. de la Ilustración 49 790763467
7 Ignacio Herrero Dominguez C/ del girasol 3 NULL
SELECT * FROM Pedidos
WHERE idPedidos = 8;
idPedidos producto descripcionProducto precio fechaPedido numeroProductos totalPrecio idClientes
8 Horno Balay Electrodoméstico 699,55 2022-09-10 2 1399,1 NULL

INNER JOIN

Es el JOIN más común. De hecho, si en nuestra SELECT solo indicamos la palabra JOIN, el sistema lo interpretará automáticamente como INNER JOIN. Esta cláusula establece una relación entre dos tablas a través de un campo común de la tabla principal y de la tabla secundaria devolviendo únicamente los registros que tengan valores coincidentes en ambas tablas.

Se pueden encadenar varios JOIN para establecer varias relaciones desde una única sentencia.

INNER JOIN

La sintáxis básica es sencilla:

SELECT columnas FROM tabla1 (INNER) JOIN tabla2 ON tabla1.campoRelacion = tabla2.campoRelacion;

El siguiente ejemplo ilustra una relación INNER JOIN entre las tablas Clientes y Pedidos:

SELECT C.idClientes,
       C.apellidos,
       P.idPedidos,
       P.producto,
       P.precio,
       P.numeroProductos
FROM Clientes C
JOIN Pedidos P
ON C.idClientes = P.idClientes
WHERE C.nombre = 'María';
idClientes apellidos idPedidos producto precio numeroProductos
2 Lopez ruiz 2 Play Station 5 549,95 4
2 Lopez ruiz 3 Xbox series X 499,99 2

De esta ejecución podemos extrapolar que el cliente de apellidos Lopez Ruiz ha hecho 2 pedidos, pudiendo ver la información de los artículos.

Existe una manera alternativa de realizar el INNER JOIN, indicando directamente las tablas a relacionar en el FROM y estableciendo la relación a través de los campos relacionados en el WHERE. La sintaxis sería:

SELECT columnas FROM tabla1, tabla2 WHERE tabla1.campoRelacion = tabla2.campoRelacion
SELECT C.idClientes,
       C.apellidos,
       P.idPedidos,
       P.producto,
       P.precio,
       P.numeroProductos
FROM Clientes C , Pedidos P
WHERE C.idClientes = P.idClientes
AND C.nombre = 'María';

Esta ejecución devolvería el mismo resultado que la anterior.

Si lanzamos una ejecución sin filtros WHERE, podemos observar que devuelve todos los registros cuyo campo común (idClientes) esté presente en ambas tablas:

SELECT C.idClientes,
       C.apellidos,
       P.idPedidos,
       P.producto,
       P.precio,
       P.numeroProductos
FROM Clientes C
INNER JOIN Pedidos P
ON C.idClientes = P.idClientes
idClientes apellidos idPedidos producto precio numeroProductos
1 García Rodriguez 4 MacBook Pro M1 2449,5 1
2 Lopez ruiz 2 Play Station 5 549,95 4
2 Lopez ruiz 3 Xbox series X 499,99 2
3 Fernandez Montero 1 Xiami Mi 11 286,95 15
4 Sanchez García 5 Echo DOT 3 39,99 50
4 Sanchez García 6 Echo DOT 4 59,99 50
5 Valero Martinez 7 Nintendo Switch 299,99 3

LEFT (OUTER) JOIN

Esta cláusula devuelve todos los registros de la tabla izquierda(Clientes) mas aquellos que intersecan ambas tablas.

LEFT JOIN

Ejecutamos la sentencia anterior sustituyendo la cláusula INNER JOIN por LEFT JOIN:

SELECT C.idClientes,
       C.apellidos,
       P.idPedidos,
       P.producto,
       P.precio,
       P.numeroProductos
FROM Clientes C
LEFT JOIN Pedidos P
ON C.idClientes = P.idClientes
idClientes apellidos idPedidos producto precio numeroProductos
1 García Rodriguez 4 MacBook Pro M1 2449,5 1
2 Lopez ruiz 2 Play Station 5 549,95 4
2 Lopez ruiz 3 Xbox series X 499,99 2
3 Fernandez Montero 1 Xiami Mi 11 286,95 15
4 Sanchez García 5 Echo DOT 3 39,99 50
4 Sanchez García 6 Echo DOT 4 59,99 50
5 Valero Martinez 7 Nintendo Switch 299,99 3
6 Sanz Valdivia NULL NULL NULL NULL
7 Herrero Dominguez NULL NULL NULL NULL

RIGHT (OUTER) JOIN

Esta cláusula devuelve todos los registros de la tabla derecha (Pedidos) mas aquellos que intersecan ambas tablas (como el INNER JOIN).

RIGHT JOIN

Ejecutamos la sentencia anterior con la cláusula RIGHT JOIN:

SELECT C.idClientes,
       C.apellidos,
       P.idPedidos,
        P.producto,
        P.precio,
         P.numeroProductos
FROM Clientes C
RIGHT JOIN Pedidos P
ON C.idClientes = P.idClientes
idClientes apellidos idPedidos producto precio numeroProductos
1 García Rodriguez 4 MacBook Pro M1 2449,5 1
2 Lopez ruiz 2 Play Station 5 549,95 4
2 Lopez ruiz 3 Xbox series X 499,99 2
3 Fernandez Montero 1 Xiami Mi 11 286,95 15
4 Sanchez García 5 Echo DOT 3 39,99 50
4 Sanchez García 6 Echo DOT 4 59,99 50
5 Valero Martinez 7 Nintendo Switch 299,99 3
NULL NULL 8 Horno Balay 699,55 2

FULL (OUTER) JOIN

Esta cláusula devuelve tanto los registros de la tabla izquierda y derecha, independientemente si intersecan o no.

FULL JOIN

Ejecutamos la sentencia anterior con la cláusula FULL JOIN:

SELECT C.idClientes,
       C.apellidos,
       P.idPedidos,
        P.producto,
        P.precio,
        P.numeroProductos
FROM Clientes C
FULL JOIN Pedidos P
ON C.idClientes = P.idClientes
idClientes apellidos idPedidos producto precio numeroProductos
1 García Rodriguez 4 MacBook Pro M1 2449,5 1
2 Lopez ruiz 2 Play Station 5 549,95 4
2 Lopez ruiz 3 Xbox series X 499,99 2
3 Fernandez Montero 1 Xiami Mi 11 286,95 15
4 Sanchez García 5 Echo DOT 3 39,99 50
4 Sanchez García 6 Echo DOT 4 59,99 50
5 Valero Martinez 7 Nintendo Switch 299,99 3
6 Sanz Valdivia NULL NULL NULL NULL
7 Herrero Dominguez NULL NULL NULL NULL
NULL NULL 8 Horno Balay 699,55 2