Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Junção de três tabelas com junções diferentes de INNER JOIN


Sim, eu uso todos esses três JOINs, embora eu tenha a tendência de usar apenas LEFT (OUTER) JOIN s em vez de misturar LEFT JOINs e RIGHT JOINs. Eu também uso FULL OUTER JOIN s e CROSS JOIN s.

Em resumo, um INNER JOIN restringe o conjunto de resultados apenas aos registros atendidos pela condição JOIN. Considere as seguintes tabelas

EDITAR: Renomeei os nomes das tabelas e prefixei-os com @ para que as variáveis ​​​​de tabela possam ser usadas para qualquer pessoa que leia esta resposta e queira experimentar.

Se você também quiser experimentar isso no navegador, configure tudo isso no SQL Fiddle também;
@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');

Um INNER JOIN Instrução SQL, unida no id campo
SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
INNER JOIN
    @Table2 t2
    ON 
        t1.id = t2.id

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

Um LEFT JOIN retornará um conjunto de resultados com todos os registros da tabela no lado esquerdo da junção (se você escrever a instrução como uma linha, a tabela que aparece primeiro) e campos da tabela no lado direito da junção que correspondem à expressão de junção e estão incluídos no SELECT cláusula. Ausente detalhes serão preenchidos com NULL
SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
LEFT JOIN
    @Table2 t2
    ON 
        t1.id = t2.id

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

Um RIGHT JOIN é a mesma lógica que um LEFT JOIN mas retornará todos os registros do lado direito da junção e os campos do lado esquerdo que correspondem à expressão de junção e estão incluídos no SELECT cláusula.
SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
RIGHT JOIN
    @Table2 t2
    ON 
        t1.id = t2.id

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

Claro, também existe o FULL OUTER JOIN , que inclui registros de ambas as tabelas unidas e preenche qualquer ausente detalhes com NULL.
SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
FULL OUTER JOIN
    @Table2 t2
    ON 
        t1.id = t2.id

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

E um CROSS JOIN (também conhecido como CARTESIAN PRODUCT ), que é simplesmente o produto de campos de aplicação cruzada no SELECT instrução de uma tabela com os campos no SELECT declaração da outra tabela. Observe que não há expressão de junção em um CROSS JOIN
SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
CROSS JOIN
    @Table2 t2

Resulta em
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:

Imagine que agora existe uma Tabela3
@Table3

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

O 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');

Agora todas as três tabelas unidas com 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

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

Pode ajudar a entender esse resultado pensando que os registros com id 2 e 3 são os únicos comuns a todas as 3 tabelas e também são o campo em que estamos juntando cada tabela.

Agora todos os três com 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

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

A resposta de Joel é uma boa explicação para explicar esse conjunto de resultados (Tabela 1 é a tabela base/origem).

Agora com um INNER JOIN e um 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

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

Embora não saibamos a ordem em que o otimizador de consulta executará as operações, examinaremos essa consulta de cima para baixo para entender o conjunto de resultados. O INNER JOIN on ids entre a Tabela1 e a Tabela2 restringirá o conjunto de resultados apenas aos registros satisfeitos pela condição de junção, ou seja, as três linhas que vimos no primeiro exemplo. Este temporário O conjunto de resultados será então LEFT JOIN ed para Tabela3 em ids entre Tabela1 e Tabelas; Existem registros na Tabela3 com id 2 e 3, mas não id 1, então o campo t3.name terá detalhes para 2 e 3, mas não 1.