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

Unisci 3 tabelle in SQL

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 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.

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)