sql >> Databáze >  >> RDS >> Database

Spojte 3 tabulky v SQL

V SQL můžete spojit tři nebo více tabulek přidáním dalšího spojení za první.

Můžete také spustit vnořená spojení zadáním jednoho spojení jako podmínky spojení pro jiné.

Syntaxe

Nejběžnější způsob spojení tří stolů vypadá asi takto:

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

Toto používá vnitřní spojení, ale můžete zadat požadovaný typ spojení jako u jakéhokoli jiného spojení. V případě potřeby můžete také kombinovat typy spojení (příklad níže).

Můžete také použít vnořená spojení zadáním jednoho spojení jako podmínky spojení pro další spojení. Takhle:

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

Ukázková data – 3 tabulky

Předpokládejme, že máme následující tři tabulky.

Customers tabulka:

+--------------+----------------+-------------- --+-----------------+| Číslo zákazníka | Jméno zákazníka | 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 dotčených řádků)

Cities tabulka:

+----------+---------------+------------------ -+---------------+| CityId | Název města | StateProvinceId | Obyvatelstvo ||----------+----------------+------------------- +---------------|| 3673 | Bow Mar | 6 | 866 || 12152 | Frankewing | 44 | NULL || 12748 | Gasport | 33 | 1248 || 21692 | Medicine Lodge | 17 | 2009 || 26483 | Peeples Valley | 3 | 428 || 33475 | Sylvanit | 27 | 103 || 17054 | Jessie | 35 | 25 || 19586 | Lisco | 28 | NULL || 37403 | Wimbledon | 35 | 216 |+----------+----------------+------------------- +--------------+(9 řádků ovlivněno)

StateProvinces tabulka:

+-------------------+---------------------+---- -----------------+-------------+--------------+| StateProvinceId | StateProvinceCode | StateProvinceName | CountryId | Populace ||-------------------+---------------------+----- ----------------+-------------+--------------|| 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 | Severní Dakota | 230 | 723393 || 44 | TN | Tennessee | 230 | 6495978 |+-------------------+---------------------+------ ----------------+-------------+--------------+(8 dotčených řádků )

Příklad 1 – Vnitřní spojení 3 stolů

Nejoblíbenějším typem spojení je vnitřní spojení, takže s ním začneme.

Zde je příklad spojení výše uvedených tří tabulek dvěma vnitřními spojeními.

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; 

Výsledek:

+---------------------+----------------+------- ---------+| StateProvinceName | Název města | Jméno zákazníka ||---------------------+----------------+-------- --------|| Nebraska | Lisco | Homer McKenzie || Kansas | Medicine Lodge | Bart Pitt || New York | Gasport | Lisa McQueen || Severní Dakota | Jessie | Steve Simpson || Tennessee | Frankewing | Vinn Allen || Colorado | Bow Mar | Veejay Smith || Severní Dakota | Wimbledon | Borat Lee |+---------------------+----------------+-------- ---------+(7 dotčených řádků)

Příklad 2 – Kombinace typů spojení

Při spojování tří nebo více stolů můžete kombinovat typy spojení.

Zde je příklad kombinace vnitřního spojení s levým spojením.

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; 

Výsledek:

---------------------+----------------+-------- --------+| StateProvinceName | Název města | Jméno zákazníka ||---------------------+----------------+-------- --------|| Colorado | Bow Mar | Veejay Smith || Tennessee | Frankewing | Vinn Allen || New York | Gasport | Lisa McQueen || Kansas | Medicine Lodge | Bart Pitt || Arizona | Peeples Valley | NULL || Severní Dakota | Jessie | Steve Simpson || Nebraska | Lisco | Homer McKenzie || Severní Dakota | Wimbledon | Borat Lee |+---------------------+----------------+-------- ---------+(8 dotčených řádků)

V tomto případě máme město (Peeples Valley), které zatím nemá žádné zákazníky.

Důvod, proč nyní tyto informace vidíme, je ten, že levé spojení vrací řádky, které obsahují data v levé tabulce, i když v levé tabulce nejsou žádné odpovídající řádky.

Předchozí příklad, který kombinoval dvě vnitřní spojení, nevrátil tento řádek, protože vnitřní spojení zahodí neshodné řádky z obou tabulek. Řádky vrací pouze tehdy, když je v obou tabulkách alespoň jeden řádek, který odpovídá podmínce spojení.

Nová ukázková data – 3 různé tabulky

Pro zbývající příklady použijeme následující tabulky.

PetTypes tabulka:

+-------------+-----------+| PetTypeId | PetType ||-------------+-----------|| 1 | Pták || 2 | Kočka || 3 | Pes || 4 | Králík |+-------------+-----------+ (dotčené 4 řádky)

Pets tabulka:

+---------+-------------+-----------+---------- -+-------------+| PetId | PetTypeId | OwnerId | Jméno mazlíčka | DOB ||---------+-------------+-----------+------------ +------------|| 1 | 2 | 3 | Načechraný | 2020-11-20 || 2 | 3 | 3 | Načíst | 2019-08-16 || 3 | 2 | 2 | Škrábnout | 2018-10-01 || 4 | 3 | 3 | Wag | 2020-03-15 || 5 | 1 | 1 | Tweet | 2020-11-28 || 6 | 3 | 4 | Načechraný | 2020-09-17 || 7 | 3 | 2 | Kůra | NULL || 8 | 2 | 4 | Mňau | NULL |+---------+-------------+-----------+----------- +------------+(8 řádků ovlivněno)

Owners tabulka:

+-----------+-------------+------------+------- ---------+-------------------+| OwnerId | Jméno | Příjmení | Telefon | E-mail ||-----------+-------------+------------+--------- --------+-------------------|| 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] |+-----------+-------------+------------+---- ------------+-------------------+

Všimněte si, že:

  • PetTypeId ve sloupci Pets tabulka je cizí klíč PetTypeId z PetTypes tabulka (což je primární klíč této tabulky).
  • OwnerId ve sloupci Pets tabulka je cizí klíč OwnerId ve sloupci Owners stůl.

Příklad 3 – Levé spojení 3 stolů

Udělejme spojení tří stolů pomocí dvou levých spojení.

Zde je příklad spuštění dvou levých spojení proti těmto tabulkám.

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; 

Výsledek:

+-----------+-----------+----------------+| Jméno mazlíčka | PetType | PetOwner ||-----------+-----------+----------------|| Tweet | Pták | Homer Connery || Škrábnout | Kočka | Bart Pitt || Kůra | Pes | Bart Pitt || Načechraný | Kočka | Nancy Simpson || Načíst | Pes | Nancy Simpson || Wag | Pes | Nancy Simpson || Načechraný | Pes | Boris Trump || Mňau | Kočka | Boris Trump || NULL | NULL | Woody Eastwood |+-----------+-----------+----------------+ (ovlivněno 9 řádků) 

Tady máme majitele domácího mazlíčka, který žádného mazlíčka nemá. Můžeme to ověřit pohledem na Pets.OwnerId a zjistíte, že neexistuje žádná hodnota, která by odpovídala OwnerId Woodyho Eastwooda v Owners tabulka.

Příklad 4 – Pravé spojení 3 stolů

Pravé spojení je opakem levého spojení. Zde je příklad s použitím stejných tří tabulek.

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; 

Výsledek:

+-----------+-----------+---------------+| Jméno mazlíčka | PetType | PetOwner ||-----------+-----------+---------------|| Tweet | Pták | Homer Connery || Načechraný | Kočka | Nancy Simpson || Škrábnout | Kočka | Bart Pitt || Mňau | Kočka | Boris Trump || Načíst | Pes | Nancy Simpson || Wag | Pes | Nancy Simpson || Načechraný | Pes | Boris Trump || Kůra | Pes | Bart Pitt || NULL | Králík | |+-----------+-----------+---------------+(9 dotčených řádků)

Tentokrát jsme dostali extra typ domácího mazlíčka (Rabbit ), ale ne další vlastník. Pravá spojení totiž vracejí řádky, které obsahují data v pravé tabulce, i když v levé tabulce nejsou žádné odpovídající řádky.

Mimochodem, důvodem je poslední PetOwner není NULL (jako poslední PetName je), protože je výsledkem zřetězení řetězců. Použil jsem T-SQL CONCAT() funkce ke zřetězení jména a příjmení vlastníka.

Příklad 5 – Úplné spojení 3 stolů

Úplné spojení je jako mít levé a pravé spojení v jednom. Vrátí všechny řádky, pokud jsou v jedné z tabulek odpovídající data.

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; 

Výsledek:

+-----------+-----------+----------------+| Jméno mazlíčka | PetType | PetOwner ||-----------+-----------+----------------|| Tweet | Pták | Homer Connery || Škrábnout | Kočka | Bart Pitt || Kůra | Pes | Bart Pitt || Načechraný | Kočka | Nancy Simpson || Načíst | Pes | Nancy Simpson || Wag | Pes | Nancy Simpson || Načechraný | Pes | Boris Trump || Mňau | Kočka | Boris Trump || NULL | NULL | Woody Eastwood || NULL | Králík | |+-----------+-----------+----------------+(10 dotčených řádků) 

Tentokrát dostaneme kombinaci výsledků, které jsme získali v předchozích dvou příkladech.

Příklad 6 – Vnořené spojení

Jak již bylo zmíněno, můžete také provádět vnořená spojení.

Zde je příklad vnořeného spojení.

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; 

Výsledek:

+-----------+-----------+----------------+| Jméno mazlíčka | PetType | PetOwner ||-----------+-----------+----------------|| Tweet | Pták | Homer Connery || Škrábnout | Kočka | Bart Pitt || Kůra | Pes | Bart Pitt || Načechraný | Kočka | Nancy Simpson || Načíst | Pes | Nancy Simpson || Wag | Pes | Nancy Simpson || Načechraný | Pes | Boris Trump || Mňau | Kočka | Boris Trump || NULL | NULL | Woody Eastwood |+-----------+-----------+----------------+ (ovlivněno 9 řádků) 

  1. MySQL DATEDIFF() vs TIMEDIFF():Jaký je rozdíl?

  2. php nahrávání souboru, jak omezit typ nahrávání souboru

  3. Prozkoumejte příčiny a řešení poškození databáze SQL Server

  4. Příklady DAYNAME() – MySQL