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 sloupciPets
tabulka je cizí klíčPetTypeId
zPetTypes
tabulka (což je primární klíč této tabulky).OwnerId
ve sloupciPets
tabulka je cizí klíčOwnerId
ve sloupciOwners
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ů)