In SQL, puoi unire tre o più tabelle aggiungendo un altro join dopo il primo.
Puoi anche eseguire join nidificati specificando un join come condizione di join per un altro.
Sintassi
Il modo più comune per unire tre tavoli è qualcosa del genere:
SELECT *
FROM Table1
INNER JOIN Table2
ON Condition
INNER JOIN Table3
ON Condition;
Questo utilizza un inner join, ma puoi specificare il tipo di join desiderato come con qualsiasi altro join. Se necessario, puoi anche combinare i tipi di join (esempio di seguito).
È inoltre possibile utilizzare i join nidificati specificando un join come condizione di join per un altro join. In questo modo:
SELECT *
FROM Table1
JOIN (Table2
JOIN Table3
ON Condition)
ON Condition;
Dati di esempio:le 3 tabelle
Supponiamo di avere le seguenti tre tabelle.
I Customers
tabella:
+--------------+----------------+----------------+----------------+ | CustomerId | CustomerName | PostalCityId | PhoneNumber | |--------------+----------------+----------------+----------------| | 1 | Homer McKenzie | 19586 | (308) 555-0100 | | 2 | Marge Pratt | 33475 | (406) 555-0100 | | 3 | Vlad Bernanke | NULL | (480) 555-0100 | | 4 | Bart Pitt | 21692 | (316) 555-0100 | | 5 | Lisa McQueen | 12748 | (212) 555-0100 | | 6 | Steve Simpson | 17054 | (701) 555-0100 | | 7 | Vinn Allen | 12152 | (423) 555-0100 | | 8 | Veejay Smith | 3673 | (303) 555-0100 | | 9 | Kasey Chin | 23805 | (201) 555-0100 | | 10 | Borat Lee | 37403 | (701) 555-0100 | +--------------+----------------+----------------+----------------+ (10 rows affected)
Le Cities
tabella:
+----------+----------------+-------------------+--------------+ | CityId | CityName | StateProvinceId | Population | |----------+----------------+-------------------+--------------| | 3673 | Bow Mar | 6 | 866 | | 12152 | Frankewing | 44 | NULL | | 12748 | Gasport | 33 | 1248 | | 21692 | Medicine Lodge | 17 | 2009 | | 26483 | Peeples Valley | 3 | 428 | | 33475 | Sylvanite | 27 | 103 | | 17054 | Jessie | 35 | 25 | | 19586 | Lisco | 28 | NULL | | 37403 | Wimbledon | 35 | 216 | +----------+----------------+-------------------+--------------+ (9 rows affected)
Le StateProvinces
tabella:
+-------------------+---------------------+---------------------+-------------+--------------+ | StateProvinceId | StateProvinceCode | StateProvinceName | CountryId | Population | |-------------------+---------------------+---------------------+-------------+--------------| | 3 | AZ | Arizona | 230 | 6891688 | | 6 | CO | Colorado | 230 | 5698265 | | 17 | KS | Kansas | 230 | 2893957 | | 28 | NE | Nebraska | 230 | 1943256 | | 31 | NJ | New Jersey | 230 | 8899339 | | 33 | NY | New York | 230 | 20437172 | | 35 | ND | North Dakota | 230 | 723393 | | 44 | TN | Tennessee | 230 | 6495978 | +-------------------+---------------------+---------------------+-------------+--------------+ (8 rows affected)
Esempio 1 – Inner Join 3 tabelle
Il tipo di join più popolare è quello interno, quindi inizieremo con quello.
Ecco un esempio di unione delle tre tabelle precedenti con due inner join.
SELECT
s.StateProvinceName,
ci.CityName,
cu.CustomerName
FROM StateProvinces s
INNER JOIN Cities AS ci
ON ci.StateProvinceID = s.StateProvinceID
INNER JOIN Customers cu
ON cu.PostalCityId = ci.CityId;
Risultato:
+---------------------+----------------+----------------+ | StateProvinceName | CityName | CustomerName | |---------------------+----------------+----------------| | Nebraska | Lisco | Homer McKenzie | | Kansas | Medicine Lodge | Bart Pitt | | New York | Gasport | Lisa McQueen | | North Dakota | Jessie | Steve Simpson | | Tennessee | Frankewing | Vinn Allen | | Colorado | Bow Mar | Veejay Smith | | North Dakota | Wimbledon | Borat Lee | +---------------------+----------------+----------------+ (7 rows affected)
Esempio 2:combinazione di tipi di join
Puoi combinare i tipi di join quando ti unisci a tre o più tavoli.
Ecco un esempio di combinazione di un inner join con un left join.
SELECT
s.StateProvinceName,
ci.CityName,
cu.CustomerName
FROM StateProvinces s
INNER JOIN Cities AS ci
ON ci.StateProvinceID = s.StateProvinceID
LEFT JOIN Customers cu
ON cu.PostalCityId = ci.CityId;
Risultato:
---------------------+----------------+----------------+ | StateProvinceName | CityName | CustomerName | |---------------------+----------------+----------------| | Colorado | Bow Mar | Veejay Smith | | Tennessee | Frankewing | Vinn Allen | | New York | Gasport | Lisa McQueen | | Kansas | Medicine Lodge | Bart Pitt | | Arizona | Peeples Valley | NULL | | North Dakota | Jessie | Steve Simpson | | Nebraska | Lisco | Homer McKenzie | | North Dakota | Wimbledon | Borat Lee | +---------------------+----------------+----------------+ (8 rows affected)
In questo caso, abbiamo una città (Peeples Valley) che non ha ancora clienti.
Il motivo per cui ora possiamo vedere queste informazioni è perché il join sinistro restituisce righe con dati nella tabella di sinistra, anche se non ci sono righe corrispondenti nella tabella di sinistra.
L'esempio precedente che combinava due inner join non ha restituito questa riga, perché gli inner join eliminano le righe non corrispondenti da entrambe le tabelle. Restituisce righe solo quando è presente almeno una riga in entrambe le tabelle che soddisfano la condizione di unione.
Nuovi dati di esempio:3 tabelle diverse
Per gli esempi rimanenti, utilizzeremo le seguenti tabelle.
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 delPets
table è una chiave esterna diPetTypeId
deiPetTypes
table (che è la chiave primaria di quella tabella). - Il
OwnerId
colonna delPets
table è una chiave esterna diOwnerId
colonna deiOwners
tabella.
Esempio 3:unisci a sinistra 3 tabelle
Facciamo un join a tre tabelle usando due join a sinistra.
Ecco un esempio di esecuzione di due left join su quelle tabelle.
SELECT
p.PetName,
pt.PetType,
CONCAT(o.FirstName, ' ', o.LastName) AS PetOwner
FROM Owners o LEFT JOIN Pets p
ON p.OwnerId = o.OwnerId
LEFT 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 | +-----------+-----------+----------------+ (9 rows affected)
Qui abbiamo un proprietario di un animale domestico che non ha un animale domestico. Possiamo verificarlo guardando Pets.OwnerId
colonna e vedendo che non c'è alcun valore che corrisponda a OwnerId
di Woody Eastwood nei Owners
tabella.
Esempio 4 – Unisci a destra 3 tabelle
Il join destro è l'opposto del join sinistro. Ecco un esempio che utilizza le stesse tre tabelle.
SELECT
p.PetName,
pt.PetType,
CONCAT(o.FirstName, ' ', o.LastName) AS PetOwner
FROM Pets p RIGHT JOIN Owners o
ON p.OwnerId = o.OwnerId
RIGHT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
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 | | +-----------+-----------+---------------+ (9 rows affected)
Questa volta abbiamo ottenuto un tipo di animale domestico in più (Rabbit
), ma non il proprietario aggiuntivo. Questo perché i join a destra restituiscono righe che contengono dati nella tabella di destra, anche se non ci sono righe corrispondenti nella tabella di sinistra.
A proposito, il motivo dell'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.
Esempio 5:unione completa di 3 tabelle
Il join completo è come avere un join sinistro e destro in uno. Restituisce tutte le righe, purché ci siano dati corrispondenti in una delle tabelle.
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 otteniamo una combinazione dei risultati che abbiamo ottenuto nei due esempi precedenti.
Esempio 6 – Join nidificati
Come accennato, puoi anche eseguire join nidificati.
Ecco un esempio di join nidificato.
SELECT
p.PetName,
pt.PetType,
CONCAT(o.FirstName, ' ', o.LastName) AS PetOwner
FROM Owners o
LEFT JOIN (Pets p
LEFT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId)
ON p.OwnerId = o.OwnerId;
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 | +-----------+-----------+----------------+ (9 rows affected)