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

SQL Full Join

Questo articolo fornisce una panoramica del FULL JOIN in SQL, oltre ad alcuni esempi di base.

Il FULL JOIN di SQL (o FULL OUTER JOIN ) restituisce tutte le righe, purché ci siano dati corrispondenti in una delle tabelle.

È come avere entrambi un join sinistro destro in un join.

Sintassi

Specificare un join completo nel FROM clausola. Puoi usare sia il FULL JOIN o FULL OUTER JOIN sintassi.

Usando il FULL JOIN sintassi:

SELECT *
FROM Table1 FULL JOIN Table2 
ON Table1.Column = Table2.Column;

Usando il FULL OUTER JOIN sintassi:

SELECT *
FROM Table1 FULL OUTER JOIN Table2 
ON Table1.Column = Table2.Column;

Entrambi fanno esattamente la stessa cosa. È solo che il OUTER la parola chiave è facoltativa.

Esempi

Ecco alcuni esempi da dimostrare.

Dati di esempio

Innanzitutto, ecco le tabelle che useremo per gli esempi.

I PetTypes tabella:

+-------------+-----------+
| PetTypeId   | PetType   |
|-------------+-----------|
| 1           | Bird      |
| 2           | Cat       |
| 3           | Dog       |
| 4           | Rabbit    |
+-------------+-----------+
(4 rows affected)

Gli Pets tabella:

+---------+-------------+-----------+-----------+------------+
| PetId   | PetTypeId   | OwnerId   | PetName   | DOB        |
|---------+-------------+-----------+-----------+------------|
| 1       | 2           | 3         | Fluffy    | 2020-11-20 |
| 2       | 3           | 3         | Fetch     | 2019-08-16 |
| 3       | 2           | 2         | Scratch   | 2018-10-01 |
| 4       | 3           | 3         | Wag       | 2020-03-15 |
| 5       | 1           | 1         | Tweet     | 2020-11-28 |
| 6       | 3           | 4         | Fluffy    | 2020-09-17 |
| 7       | 3           | 2         | Bark      | NULL       |
| 8       | 2           | 4         | Meow      | NULL       |
+---------+-------------+-----------+-----------+------------+
(8 rows affected)

I Owners tabella:

+-----------+-------------+------------+----------------+-------------------+
| OwnerId   | FirstName   | LastName   | Phone          | Email             |
|-----------+-------------+------------+----------------+-------------------|
| 1         | Homer       | Connery    | (308) 555-0100 | [email protected] |
| 2         | Bart        | Pitt       | (231) 465-3497 | [email protected]  |
| 3         | Nancy       | Simpson    | (489) 591-0408 | NULL              |
| 4         | Boris       | Trump      | (349) 611-8908 | NULL              |
| 5         | Woody       | Eastwood   | (308) 555-0112 | [email protected] |
+-----------+-------------+------------+----------------+-------------------+

Nota che:

  • Il PetTypeId colonna del Pets table è una chiave esterna di PetTypeId dei PetTypes table (che è la chiave primaria di quella tabella).
  • Il OwnerId colonna del Pets table è una chiave esterna di OwnerId colonna dei Owners tabella.

La query di partecipazione completa

Ecco un esempio di esecuzione di un full join su due di queste tabelle.

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
FULL JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;

Risultato:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Tweet     | Bird      |
| Fluffy    | Cat       |
| Scratch   | Cat       |
| Meow      | Cat       |
| Fetch     | Dog       |
| Wag       | Dog       |
| Fluffy    | Dog       |
| Bark      | Dog       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

In questo esempio, otteniamo un PetType valore che non corrisponde a un PetName . Questo perché non ci sono conigli come animali domestici. Ma il join completo provoca Rabbit da restituire, anche se non ci sono animali nel Pets tabella di quel tipo. Ciò risulta in un NULL valore nel PetName colonna contro Rabbit .

Questo è lo stesso risultato che avremmo ottenuto se avessimo usato un join corretto, perché PetTypes la tabella è a destra di JOIN parola chiave. Questo non sarebbe successo con un join sinistro, perché PetTypes la tabella non è a sinistra di JOIN parola chiave. Se volessimo ricrearlo con un join sinistro, dovremmo cambiare l'ordine delle tabelle, in modo che i PetTypes la tabella era a sinistra di JOIN parola chiave.

Ecco cosa succede se cambiamo l'ordine della tabella nella nostra query quando si utilizza un join completo.

SELECT 
    p.PetName,
    pt.PetType
FROM PetTypes pt
FULL JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;

Risultato:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Tweet     | Bird      |
| Fluffy    | Cat       |
| Scratch   | Cat       |
| Meow      | Cat       |
| Fetch     | Dog       |
| Wag       | Dog       |
| Fluffy    | Dog       |
| Bark      | Dog       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

Otteniamo esattamente lo stesso risultato. Questo perché il join completo restituisce tutte le righe, purché ci siano dati corrispondenti in una delle tabelle. Come accennato, è come avere un join sinistro e destro in un join.

Full Join su 3 tavoli

Ecco un esempio di esecuzione di un full join su tutti e tre i tavoli.

SELECT 
    p.PetName,
    pt.PetType,
    CONCAT(o.FirstName, ' ', o.LastName) AS PetOwner
FROM Owners o FULL JOIN Pets p
    ON p.OwnerId = o.OwnerId
FULL JOIN PetTypes pt
    ON p.PetTypeId = pt.PetTypeId;

Risultato:

+-----------+-----------+----------------+
| PetName   | PetType   | PetOwner       |
|-----------+-----------+----------------|
| Tweet     | Bird      | Homer Connery  |
| Scratch   | Cat       | Bart Pitt      |
| Bark      | Dog       | Bart Pitt      |
| Fluffy    | Cat       | Nancy Simpson  |
| Fetch     | Dog       | Nancy Simpson  |
| Wag       | Dog       | Nancy Simpson  |
| Fluffy    | Dog       | Boris Trump    |
| Meow      | Cat       | Boris Trump    |
| NULL      | NULL      | Woody Eastwood |
| NULL      | Rabbit    |                |
+-----------+-----------+----------------+
(10 rows affected)

Questa volta abbiamo un proprietario di un animale domestico che non ha un animale domestico, così come un tipo di animale domestico che non è assegnato a un animale domestico.

Se mescoliamo l'ordine delle tabelle, otteniamo lo stesso risultato, sebbene le righe siano elencate in un ordine diverso.

SELECT 
    p.PetName,
    pt.PetType,
    CONCAT(o.FirstName, ' ', o.LastName) AS PetOwner
FROM PetTypes pt FULL JOIN Pets p
    ON p.PetTypeId = pt.PetTypeId
FULL JOIN Owners o 
    ON p.OwnerId = o.OwnerId;

Risultato:

-----------+-----------+----------------+
| PetName   | PetType   | PetOwner       |
|-----------+-----------+----------------|
| Tweet     | Bird      | Homer Connery  |
| Fluffy    | Cat       | Nancy Simpson  |
| Scratch   | Cat       | Bart Pitt      |
| Meow      | Cat       | Boris Trump    |
| Fetch     | Dog       | Nancy Simpson  |
| Wag       | Dog       | Nancy Simpson  |
| Fluffy    | Dog       | Boris Trump    |
| Bark      | Dog       | Bart Pitt      |
| NULL      | Rabbit    |                |
| NULL      | NULL      | Woody Eastwood |
+-----------+-----------+----------------+
(10 rows affected)

E se li mescoliamo ancora una volta, otteniamo sempre lo stesso risultato.

SELECT 
    p.PetName,
    pt.PetType,
    CONCAT(o.FirstName, ' ', o.LastName) AS PetOwner
FROM Pets p FULL JOIN Owners o
    ON p.OwnerId = o.OwnerId
FULL JOIN PetTypes pt
    ON p.PetTypeId = pt.PetTypeId;

Risultato:

+-----------+-----------+----------------+
| PetName   | PetType   | PetOwner       |
|-----------+-----------+----------------|
| Fluffy    | Cat       | Nancy Simpson  |
| Fetch     | Dog       | Nancy Simpson  |
| Scratch   | Cat       | Bart Pitt      |
| Wag       | Dog       | Nancy Simpson  |
| Tweet     | Bird      | Homer Connery  |
| Fluffy    | Dog       | Boris Trump    |
| Bark      | Dog       | Bart Pitt      |
| Meow      | Cat       | Boris Trump    |
| NULL      | NULL      | Woody Eastwood |
| NULL      | Rabbit    |                |
+-----------+-----------+----------------+
(10 rows affected)

Se ti stai chiedendo perché l'ultimo PetOwner non è NULL (come ultimo il PetName is), è perché è il risultato di una concatenazione di stringhe. Ho usato T-SQL CONCAT() funzione per concatenare il nome e il cognome del proprietario.