Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Join di tre tabelle con join diversi da INNER JOIN

Sì, uso tutti e tre questi JOIN, anche se tendo a usare solo LEFT (OUTER) JOIN s invece di mischiare LEFT e RIGHT JOIN. Uso anche FULL OUTER JOIN se CROSS JOIN s.

In sintesi, un INNER JOIN limita il set di risultati solo ai record soddisfatti dalla condizione JOIN. Considera le seguenti tabelle

MODIFICA: Ho rinominato i nomi delle tabelle e li ho prefissi con @ in modo che le variabili di tabella possano essere utilizzate per chiunque legga questa risposta e desideri sperimentare.

Se desideri sperimentare anche questo nel browser, Ho impostato tutto su SQL Fiddle anche tu;

@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

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

Un INNER JOIN Istruzione SQL, unita su id campo

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

Risultati in

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

Un LEFT JOIN restituirà un set di risultati con tutti i record della tabella sul lato sinistro del join (se dovessi scrivere l'istruzione come una riga, la tabella che appare per prima) e i campi della tabella sul lato destro del join che corrispondono all'espressione di join e sono inclusi in SELECT clausola. Mancante i dettagli verranno compilati con NULL

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

Risultati in

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

Un RIGHT JOIN è la stessa logica di un LEFT JOIN ma restituirà tutti i record dal lato destro del join e i campi dal lato sinistro che corrispondono all'espressione del join e sono inclusi nel SELECT clausola.

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

Risultati in

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

Naturalmente, c'è anche il FULL OUTER JOIN , che include i record di entrambe le tabelle unite e popola tutti i mancanti dettagli con NULL.

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

Risultati in

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

E un CROSS JOIN (noto anche come CARTESIAN PRODUCT ), che è semplicemente il prodotto di campi di applicazione incrociati nel SELECT istruzione da una tabella con i campi in SELECT affermazione dall'altra tabella. Si noti che non esiste un'espressione di join in un CROSS JOIN

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

Risultati in

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

MODIFICA:

Immagina che ora ci sia un Table3

@Table3

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

Il codice 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');

Ora tutte e tre le tabelle sono unite 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

Risultati in

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

Potrebbe essere utile comprendere questo risultato pensando che i record con ID 2 e 3 siano gli unici comuni a tutte e 3 le tabelle e sono anche il campo in cui ci uniamo a ogni tavolo.

Ora tutti e tre 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

Risultati in

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 risposta di Joel è una buona spiegazione per spiegare questo set di risultati (la tabella 1 è la tabella di base/origine).

Ora con un INNER JOIN e 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

Risultati in

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

Sebbene non conosciamo l'ordine in cui Query Optimizer eseguirà le operazioni, esamineremo questa query dall'alto verso il basso per comprendere il set di risultati. Il INNER JOIN su id tra Table1 e Table2 limiterà il set di risultati solo ai record soddisfatti dalla condizione di join, ovvero le tre righe che abbiamo visto nel primo esempio. Questo temporaneo il set di risultati sarà quindi LEFT JOIN ed a Table3 sugli ID tra Table1 e Tables; Ci sono record in Table3 con id 2 e 3, ma non id 1, quindi il campo t3.name conterrà i dettagli per 2 e 3 ma non 1.