sql >> Database >  >> RDS >> Database

Word lid van 3 tabellen in SQL

In SQL kun je drie of meer tabellen samenvoegen door nog een keer toe te voegen na de eerste.

U kunt ook geneste joins uitvoeren door een join op te geven als de join-voorwaarde voor een andere.

Syntaxis

De meest gebruikelijke manier om aan drie tafels deel te nemen gaat ongeveer als volgt:

SELECT *
FROM Table1 
INNER JOIN Table2
    ON Condition
INNER JOIN Table3
    ON Condition;

Dit maakt gebruik van een inner join, maar u kunt het gewenste jointype specificeren zoals bij elke andere join. Je kunt desgewenst ook join-typen combineren (voorbeeld hieronder).

U kunt geneste joins ook gebruiken door één join op te geven als de join-voorwaarde voor een andere join. Zoals dit:

SELECT *
FROM Table1 
JOIN (Table2
            JOIN Table3
            ON Condition)
ON Condition;

Voorbeeldgegevens – De 3 tabellen

Stel dat we de volgende drie tabellen hebben.

De Customers tafel:

+--------------+----------------+----------------+----------------+
| 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)

De Cities tafel:

+----------+----------------+-------------------+--------------+
| 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)

De StateProvinces tafel:

+-------------------+---------------------+---------------------+-------------+--------------+
| 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)

Voorbeeld 1 – Innerlijke join 3 tabellen

Het meest populaire join-type is de inner join, dus daar beginnen we mee.

Hier is een voorbeeld van het samenvoegen van de bovenstaande drie tabellen met twee inner joins.

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;

Resultaat:

+---------------------+----------------+----------------+
| 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)

Voorbeeld 2 – Combinatietypen combineren

U kunt samenvoegingstypen combineren wanneer u aan drie of meer tafels deelneemt.

Hier is een voorbeeld van het combineren van een inner join met een 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;

Resultaat:

---------------------+----------------+----------------+
| 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 dit geval hebben we een stad (Peeples Valley) die nog geen klanten heeft.

De reden dat we die informatie nu kunnen zien, is omdat de linkerjoin rijen retourneert die gegevens in de linkertabel hebben, zelfs als er geen overeenkomende rijen in de linkertabel zijn.

In het vorige voorbeeld waarin twee inner joins werden gecombineerd, werd deze rij niet geretourneerd, omdat bij inner joins niet-overeenkomende rijen uit beide tabellen worden verwijderd. Er worden alleen rijen geretourneerd als er in beide tabellen ten minste één rij is die overeenkomt met de join-voorwaarde.

Nieuwe voorbeeldgegevens – 3 verschillende tabellen

Voor de overige voorbeelden gebruiken we de volgende tabellen.

De PetTypes tafel:

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

De Pets tafel:

+---------+-------------+-----------+-----------+------------+
| 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)

De Owners tafel:

+-----------+-------------+------------+----------------+-------------------+
| 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] |
+-----------+-------------+------------+----------------+-------------------+

Merk op dat:

  • De PetTypeId kolom van de Pets tabel is een externe sleutel van de PetTypeId van de PetTypes tabel (wat de primaire sleutel van die tabel is).
  • De OwnerId kolom van de Pets tabel is een externe sleutel van de OwnerId kolom van de Owners tafel.

Voorbeeld 3 – Linker 3 tafels samenvoegen

Laten we een three-table join doen met twee left joins.

Hier is een voorbeeld van het uitvoeren van twee left joins tegen die tafels.

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;

Resultaat:

+-----------+-----------+----------------+
| 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)

Hier hebben we een huisdiereigenaar die geen huisdier heeft. We kunnen dat verifiëren door te kijken naar de Pets.OwnerId kolom, en zien dat er geen waarde is die overeenkomt met Woody Eastwood's OwnerId in de Owners tafel.

Voorbeeld 4 – 3 tabellen rechts samenvoegen

De rechter join is het tegenovergestelde van de linker join. Hier is een voorbeeld waarin dezelfde drie tabellen worden gebruikt.

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;

Resultaat:

+-----------+-----------+---------------+
| 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)

Deze keer kregen we een extra huisdiertype (Rabbit .) ), maar niet de extra eigenaar. Dit komt omdat right joins rijen retourneren die gegevens in de rechtertabel hebben, zelfs als er geen overeenkomende rijen in de linkertabel zijn.

Trouwens, de reden waarom de laatste PetOwner is niet NULL (zoals de laatste PetName is) is omdat het het resultaat is van een aaneenschakeling van tekenreeksen. Ik gebruikte de T-SQL CONCAT() functie om de voor- en achternaam van de eigenaar samen te voegen.

Voorbeeld 5 – Volledige deelname aan 3 tabellen

De volledige join is alsof je een linker en rechter join in één hebt. Het retourneert alle rijen, zolang er overeenkomende gegevens in een van de tabellen zijn.

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;

Resultaat:

+-----------+-----------+----------------+
| 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)

Deze keer krijgen we een combinatie van de resultaten die we in de vorige twee voorbeelden kregen.

Voorbeeld 6 – Geneste joins

Zoals eerder vermeld, kunt u ook geneste joins maken.

Hier is een voorbeeld van een geneste join.

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;

Resultaat:

+-----------+-----------+----------------+
| 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)

  1. Is het mogelijk om parameters voor de tabel- of kolomnaam op te geven in Prepared Statements of QueryRunner.update()?

  2. Top drie trends die van invloed zijn op DBA's die verantwoordelijk zijn voor SQL Server-bewaking

  3. Waar haal ik de libpq-bron vandaan?

  4. Hoe 'Systeembron overschreden' te repareren bij migratie naar Windows 10