sql >> Base de Datos >  >> RDS >> Sqlserver

Combinación de tres tablas con combinaciones que no sean INNER JOIN

Sí, uso los tres JOIN, aunque tiendo a usar solo LEFT (OUTER) JOIN s en lugar de entremezclar LEFT y RIGHT JOIN. También uso FULL OUTER JOIN s y CROSS JOIN s.

En resumen, un INNER JOIN restringe el conjunto de resultados solo a aquellos registros satisfechos por la condición JOIN. Considere las siguientes tablas

EDITAR: He cambiado el nombre de los nombres de las tablas y les he puesto el prefijo @ para que las Variables de la tabla puedan usarse para cualquier persona que lea esta respuesta y quiera experimentar.

Si también desea experimentar con esto en el navegador, he configurado todo esto en SQL Fiddle también;

@Table1

id | name
---------
1  | One
2  | Two
3  | Three
4  | Four

@Table2

id | name
---------
1  | Partridge
2  | Turtle Doves
3  | French Hens
5  | Gold Rings

Código SQL

DECLARE @Table1 TABLE (id INT PRIMARY KEY CLUSTERED, [name] VARCHAR(25))

INSERT INTO @Table1 VALUES(1, 'One');
INSERT INTO @Table1 VALUES(2, 'Two');
INSERT INTO @Table1 VALUES(3, 'Three');
INSERT INTO @Table1 VALUES(4, 'Four');

DECLARE @Table2 TABLE (id INT PRIMARY KEY CLUSTERED, [name] VARCHAR(25))

INSERT INTO @Table2 VALUES(1, 'Partridge');
INSERT INTO @Table2 VALUES(2, 'Turtle Doves');
INSERT INTO @Table2 VALUES(3, 'French Hens');
INSERT INTO @Table2 VALUES(5, 'Gold Rings');

Una INNER JOIN Sentencia SQL, unida en el id campo

SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
INNER JOIN
    @Table2 t2
    ON 
        t1.id = t2.id

Resultados en

id | name | name
----------------
1  | One  | Partridge
2  | Two  | Turtle Doves
3  | Three| French Hens

A LEFT JOIN devolverá un conjunto de resultados con todos los registros de la tabla en el lado izquierdo de la unión (si tuviera que escribir la declaración como una sola línea, la tabla que aparece primero) y los campos de la tabla en el lado derecho de la unión que coinciden con la expresión de combinación y se incluyen en SELECT cláusula. Desaparecido los detalles se completarán con NULL

SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
LEFT JOIN
    @Table2 t2
    ON 
        t1.id = t2.id

Resultados en

id | name | name
----------------
1  | One  | Partridge
2  | Two  | Turtle Doves
3  | Three| French Hens
4  | Four | NULL

UN RIGHT JOIN es la misma lógica que LEFT JOIN pero devolverá todos los registros del lado derecho de la combinación y los campos del lado izquierdo que coincidan con la expresión de combinación y estén incluidos en SELECT cláusula.

SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
RIGHT JOIN
    @Table2 t2
    ON 
        t1.id = t2.id

Resultados en

id | name | name
----------------
1  | One  | Partridge
2  | Two  | Turtle Doves
3  | Three| French Hens
NULL| NULL| Gold Rings

Por supuesto, también está la FULL OUTER JOIN , que incluye registros de ambas tablas unidas y completa cualquier faltante detalles con NULL.

SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
FULL OUTER JOIN
    @Table2 t2
    ON 
        t1.id = t2.id

Resultados en

id | name | name
----------------
1  | One  | Partridge
2  | Two  | Turtle Doves
3  | Three| French Hens
4  | Four | NULL
NULL| NULL| Gold Rings

Y un CROSS JOIN (también conocido como CARTESIAN PRODUCT ), que es simplemente el producto de la aplicación cruzada de campos en SELECT declaración de una tabla con los campos en SELECT declaración de la otra mesa. Tenga en cuenta que no hay una expresión de unión en un CROSS JOIN

SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
CROSS JOIN
    @Table2 t2

Resultados en

id | name  | name
------------------
1  | One   | Partridge
2  | Two   | Partridge
3  | Three | Partridge
4  | Four  | Partridge
1  | One   | Turtle Doves
2  | Two   | Turtle Doves
3  | Three | Turtle Doves
4  | Four  | Turtle Doves
1  | One   | French Hens
2  | Two   | French Hens
3  | Three | French Hens
4  | Four  | French Hens
1  | One   | Gold Rings
2  | Two   | Gold Rings
3  | Three | Gold Rings
4  | Four  | Gold Rings

EDITAR:

Imagina que ahora hay una Table3

@Table3

id | name
---------
2  | Prime 1
3  | Prime 2
5  | Prime 3

El código SQL

DECLARE @Table3 TABLE (id INT PRIMARY KEY CLUSTERED, [name] VARCHAR(25))

INSERT INTO @Table3 VALUES(2, 'Prime 1');
INSERT INTO @Table3 VALUES(3, 'Prime 2');
INSERT INTO @Table3 VALUES(5, 'Prime 3');

Ahora las tres tablas se unieron con INNER JOINS

SELECT 
    t1.id,
    t1.name,
    t2.name,
    t3.name
FROM
    @Table1 t1
INNER JOIN
    @Table2 t2
    ON 
        t1.id = t2.id
INNER JOIN
    @Table3 t3
    ON 
        t1.id = t3.id

Resultados en

id | name | name         | name
-------------------------------
2  | Two  | Turtle Doves | Prime 1
3  | Three| French Hens  | Prime 2

Podría ayudar a entender este resultado pensando que los registros con id 2 y 3 son los únicos comunes a las 3 tablas y también son el campo en el que nos unimos a cada mesa.

Ahora los tres con LEFT JOINS

SELECT 
    t1.id,
    t1.name,
    t2.name,
    t3.name
FROM
    @Table1 t1
LEFT JOIN
    @Table2 t2
    ON 
        t1.id = t2.id
LEFT JOIN
    @Table3 t3
    ON 
        t1.id = t3.id

Resultados en

id | name | name         | name
-------------------------------
1  | One  | Partridge    | NULL
2  | Two  | Turtle Doves | Prime 1
3  | Three| French Hens  | Prime 2
4  | Four | NULL         | NULL

La respuesta de Joel es una buena explicación para explicar este conjunto de resultados (Tabla 1 es la tabla base/origen).

Ahora con un INNER JOIN y un LEFT JOIN

SELECT 
    t1.id,
    t1.name,
    t2.name,
    t3.name
FROM
    @Table1 t1
INNER JOIN
    @Table2 t2
    ON 
        t1.id = t2.id
LEFT JOIN
    @Table3 t3
    ON 
        t1.id = t3.id

Resultados en

id | name | name         | name
-------------------------------
1  | One  | Partridge    | NULL
2  | Two  | Turtle Doves | Prime 1
3  | Three| French Hens  | Prime 2

Aunque no conocemos el orden en que el optimizador de consultas realizará las operaciones, analizaremos esta consulta de arriba a abajo para comprender el conjunto de resultados. La INNER JOIN on ids between Table1 and Table2 restringirá el conjunto de resultados a solo aquellos registros satisfechos por la condición de combinación, es decir, las tres filas que vimos en el primer ejemplo. Este temporal el conjunto de resultados será LEFT JOIN ed to Table3 en ids entre Table1 y Tables; Hay registros en Table3 con id 2 y 3, pero no id 1, por lo que el campo t3.name tendrá detalles para 2 y 3 pero no para 1.