En SQL-koppling är där du kör en fråga som sammanfogar flera tabeller.
Denna handledning för SQL joins presenterar grundläggande exempel på SQL joins, samt en introduktion till de olika jointyperna.
SQL-anslutningstyper
ANSI SQL-standarden specificerar fem typer av joins, enligt listan i följande tabell.
Gå med | Beskrivning |
---|---|
INNER JOIN | Returnerar rader när det finns minst en rad i båda tabellerna som matchar kopplingsvillkoret. |
LEFT OUTER JOIN eller LEFT JOIN | Returnerar rader som har data i den vänstra tabellen (till vänster om JOIN sökord), även om det inte finns några matchande rader i den högra tabellen. |
RIGHT OUTER JOIN eller RIGHT JOIN | Returnerar rader som har data i den högra tabellen (till höger om JOIN sökord), även om det inte finns några matchande rader i den vänstra tabellen. |
FULL OUTER JOIN eller FULL JOIN | Returnerar alla rader, så länge det finns matchande data i en av tabellerna. |
CROSS JOIN | Returnerar rader som kombinerar varje rad från den första tabellen med varje rad från den andra tabellen. |
Det finns även andra villkor för olika join-operationer, såsom följande:
Gå med | Beskrivning |
---|---|
Gå med själv | När ett bord förenas med sig självt. |
Naturlig koppling | En implicit sammanfogning baserad på de gemensamma kolumnerna i de två tabellerna som sammanfogas. |
Equi-join | En join som endast innehåller likhetsjämförelser i join-predikatet. |
SQL Join Syntax
Inre kopplingar kan anges i antingen FROM
eller WHERE
klausuler. Yttre kopplingar och korskopplingar kan anges i FROM
endast klausul.
För att skapa en SQL gå med i FROM
klausul, gör något så här:
SELECT *
FROM Table1 < JoinType > Table2 [ ON ( JoinCondition ) ]
Där JoinType
anger vilken typ av anslutning som utförs och JoinCondition
definierar predikatet som ska utvärderas för varje par av sammanfogade rader.
För att ange en koppling i WHERE
klausul, gör något så här:
SELECT *
FROM Table1, Table2 [ WHERE ( JoinCondition ) ]
Återigen, JoinCondition
definierar predikatet som ska utvärderas för varje par av sammanfogade rader.
Allt inom hakparenteser ([]
) är valfritt.
Exempeltabeller för exemplen i denna självstudiekurs
De flesta av exemplen i denna handledning utför kopplingar mot följande två tabeller.
PetTypes
tabell:
+-------------+-----------+ | PetTypeId | PetType | |-------------+-----------| | 1 | Bird | | 2 | Cat | | 3 | Dog | | 4 | Rabbit | +-------------+-----------+ (4 rows affected)
Pets
tabell:
+---------+-------------+-----------+-----------+------------+ | 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)
The Inner Join
SQL INNER JOIN
returnerar rader när det finns minst en rad i båda tabellerna som matchar kopplingsvillkoret.
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets
INNER JOIN PetTypes
ON Pets.PetTypeId = PetTypes.PetTypeId;
Resultat:
-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | +-----------+-----------+ (8 rows affected)
För att ange en inre koppling i FROM
klausul använder vi INNER JOIN
. Vi använder också ON
nyckelord för att definiera predikatet som ska utvärderas för varje par sammanfogade rader.
Oavsett kopplingstyp kvalificerar vi våra kolumnnamn med tabellnamnen. Anledningen till att vi gör detta är för att undvika oklarheter angående kolumnnamnen mellan tabellerna. Båda tabellerna kan ha kolumner med samma namn (som i vårt exempel), och i sådana fall kommer DBMS inte att veta vilken kolumn du hänvisar till. Att prefixa kolumnnamnen med deras tabellnamn säkerställer att du hänvisar till höger kolumn och förhindrar eventuella fel som kan uppstå på grund av oklarheter om vilken kolumn du hänvisar till.
I det här exemplet har båda tabellerna ett PetTypeId
kolumn. Pets.PetTypeId
kolumnen är en främmande nyckel till PetTypes.PetTypeId
kolumn, som är den primära nyckeln för den tabellen.
I det här exemplet kan vi se att alla husdjur returneras, men inte alla husdjurstyper returneras. Det finns inga kaniner i Pets
tabellen, och så Rabbits
husdjurstyp returneras inte.
Anledningen till Rabbits
typ inte returneras beror på att INNER JOIN
returnerar endast rader när det finns minst en rad i båda tabellerna som matchar kopplingsvillkoret. I det här fallet, Rabbits
finns bara i en tabell (PetTypes
tabell).
Observera att anslutningstypen är valfri. Därför tillåter de flesta (om inte alla) DBMS dig att utelämna INNER
nyckelord. När du utelämnar detta (dvs. anger bara JOIN
), antas det vara en inre sammanfogning.
Därför skulle vi kunna skriva om exemplet ovan till detta:
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets
JOIN PetTypes
ON Pets.PetTypeId = PetTypes.PetTypeId;
Dessutom, som med alla SQL-satser, FROM
klausul kan vara på en hel rad om du föredrar:
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets JOIN PetTypes ON Pets.PetTypeId = PetTypes.PetTypeId;
Alias
Det är vanligt att använda tabellalias när du utför SQL-kopplingar. Alias hjälper till att göra koden mer kortfattad och lättare att läsa.
Därför kunde vi ändra det tidigare exemplet till detta:
SELECT
p.PetName,
pt.PetType
FROM Pets p INNER JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Resultat:
-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | +-----------+-----------+ (8 rows affected)
Equi-Join
Ovanstående koppling kan också hänvisas till som en equi-join . En equi-join är en join som endast innehåller likhetsjämförelser i join-predikatet.
Ett annat sätt att skriva ovanstående join är så här:
SELECT
p.PetName,
pt.PetType
FROM
Pets p,
PetTypes pt
WHERE p.PetTypeId = pt.PetTypeId;
Resultat:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | +-----------+-----------+
Detta är ett exempel på att specificera en inre koppling i WHERE
klausul. Vi gav helt enkelt en kommaseparerad lista över tabellerna och sedan en WHERE
tillstånd. Om vi hade utelämnat WHERE
villkor, skulle vi ha slutat med en CROSS JOIN
.
Många nybörjare tycker att ovanstående syntax är mycket lättare att förstå än INNER JOIN
syntax. Använd gärna denna syntax om du föredrar det, men tänk på att de flesta SQL-proffs föredrar att använda INNER JOIN
syntax från föregående exempel.
Se SQL Inner Join för fler exempel, inklusive en inre join som sammanfogar tre tabeller.
Rätt koppling
Även känd som RIGHT OUTER JOIN
, RIGHT JOIN
returnerar rader som har data i den högra tabellen (till höger om JOIN
sökord), även om det inte finns några matchande rader i den vänstra tabellen.
SELECT
p.PetName,
pt.PetType
FROM Pets p
RIGHT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Resultat:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Tweet | Bird | | Fluffy | Cat | | Scratch | Cat | | Meow | Cat | | Fetch | Dog | | Wag | Dog | | Fluffy | Dog | | Bark | Dog | | NULL | Rabbit | +-----------+-----------+ (9 rows affected)
I det här fallet fick vi en extra PetType
värde – Rabbit
– även om det inte finns något husdjur i Pets
bord av den typen. Detta resulterar i en NULL
värde i PetName
kolumn mot Rabbit
.
Se SQL Right Join för fler exempel, inklusive en högerkoppling som sammanfogar tre tabeller.
Vänstern går med
Även känd som LEFT OUTER JOIN
, SQL LEFT JOIN
returnerar rader som har data i den vänstra tabellen (vänster om JOIN
sökord), även om det inte finns några matchande rader i den högra tabellen.
Detta är motsatsen till RIGHT JOIN
.
Om vi ändrar föregående exempel till att använda en vänsterkoppling får vi följande resultat.
SELECT
p.PetName,
pt.PetType
FROM Pets p
LEFT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Resultat:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | +-----------+-----------+ (8 rows affected)
I det här specifika fallet är våra resultat desamma som med den inre sammanfogningen.
Men om vi byter bordsordning i vår FROM
sats, får vi ett liknande resultat som den högra kopplingen i föregående exempel.
SELECT
p.PetName,
pt.PetType
FROM PetTypes pt
LEFT JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;
Resultat:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Tweet | Bird | | Fluffy | Cat | | Scratch | Cat | | Meow | Cat | | Fetch | Dog | | Wag | Dog | | Fluffy | Dog | | Bark | Dog | | NULL | Rabbit | +-----------+-----------+ (9 rows affected)
Så du kan se att eventuella resulterande skillnader mellan vänster och höger kopplingar enbart beror på hur du ordnar kolumnerna i FROM
klausul.
Se SQL Left Join för fler exempel, inklusive en vänsterjoin som sammanfogar tre tabeller.
Full anslutning
SQL FULL JOIN
(eller FULL OUTER JOIN
) returnerar alla rader, så länge det finns matchande data i en av tabellerna.
Med andra ord, det är som att ha både vänster och höger join i en join.
Här är ett exempel på en fullständig anslutning.
SELECT
p.PetName,
pt.PetType
FROM Pets p
FULL JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Resultat:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | | NULL | Rabbit | +-----------+-----------+ (9 rows affected)
Detta returnerar samma resultat som vi fick med den högra kopplingen, men det skulle ha returnerat ett annat resultat om det hade funnits en rad i den vänstra tabellen som inte hade ett motsvarande värde i den högra tabellen.
Låt oss byta tabellnamnen och köra den igen.
SELECT
p.PetName,
pt.PetType
FROM PetTypes pt
FULL JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;
Resultat:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Tweet | Bird | | Fluffy | Cat | | Scratch | Cat | | Meow | Cat | | Fetch | Dog | | Wag | Dog | | Fluffy | Dog | | Bark | Dog | | NULL | Rabbit | +-----------+-----------+ (9 rows affected)
Samma resultat.
Se SQL Full Join för fler exempel, inklusive en full join som sammanfogar tre tabeller.
The Cross Join
SQL CROSS JOIN
returnerar rader som kombinerar varje rad från den första tabellen med varje rad från den andra tabellen.
Med andra ord returnerar den den kartesiska produkten av rader från tabeller i kopplingen.
SELECT
p.PetName,
pt.PetType
FROM Pets p
CROSS JOIN PetTypes pt;
Resultat:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Bird | | Fetch | Bird | | Scratch | Bird | | Wag | Bird | | Tweet | Bird | | Fluffy | Bird | | Bark | Bird | | Meow | Bird | | Fluffy | Cat | | Fetch | Cat | | Scratch | Cat | | Wag | Cat | | Tweet | Cat | | Fluffy | Cat | | Bark | Cat | | Meow | Cat | | Fluffy | Dog | | Fetch | Dog | | Scratch | Dog | | Wag | Dog | | Tweet | Dog | | Fluffy | Dog | | Bark | Dog | | Meow | Dog | | Fluffy | Rabbit | | Fetch | Rabbit | | Scratch | Rabbit | | Wag | Rabbit | | Tweet | Rabbit | | Fluffy | Rabbit | | Bark | Rabbit | | Meow | Rabbit | +-----------+-----------+ (32 rows affected)
Som du säkert kan föreställa dig kan detta vara mycket farligt om du kör det mot fel bord.
Det är samma sak som att göra detta:
SELECT
p.PetName,
pt.PetType
FROM Pets p, PetTypes pt;
Du kan lägga till en WHERE
sats till en korsfogning, vilket kommer att förvandla den till en inre sammanfogning.
Så här:
SELECT
p.PetName,
pt.PetType
FROM Pets p
CROSS JOIN PetTypes pt
WHERE p.PetTypeId = pt.PetTypeId;
Resultat:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | +-----------+-----------+ (8 rows affected)
Se SQL Cross Join för fler exempel.
The Natural Join
SQL NATURAL JOIN
är en typ av equi-join där join-predikatet uppstår implicit genom att jämföra alla kolumner i båda tabellerna som har samma kolumnnamn i de sammanfogade tabellerna.
Resultatuppsättningen innehåller endast en kolumn för varje par med lika namngivna kolumner. Om inga kolumner med samma namn hittas blir resultatet en korskoppling.
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets NATURAL JOIN PetTypes;
Resultat:
petname | pettype ---------+--------- Fluffy | Cat Fetch | Dog Scratch | Cat Wag | Dog Tweet | Bird Fluffy | Dog Bark | Dog Meow | Cat (8 rows)
Egentligen är den naturliga sammanfogningen faktiskt inte en sammanfogningstyp, enligt ANSI-standarden. Det är ett nyckelord som du valfritt kan infoga för att göra kopplingen till en naturlig koppling.
Därför kan vi ändra exemplet ovan till NATURAL INNER JOIN
om vi ville:
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets NATURAL INNER JOIN PetTypes;
Som nämnts tidigare är inre kopplingar standard kopplingstyp, så om du utelämnar kopplingstypen (t.ex. INNER
, LEFT
, RIGHT
, etc), så behandlas den som en inre sammanfogning.
Om formateringen av dessa resultat ser annorlunda ut än de tidigare resultaten, beror det på att jag var tvungen att hoppa över till PostgreSQL för att köra den här frågan. Jag körde de tidigare exemplen i SQL Server, men SQL Server stöder inte den naturliga anslutningen.
Se SQL Natural Join för fler exempel, inklusive en naturlig join som sammanfogar tre tabeller.
The Self Join
SQL SELF JOIN
ansluter sig till ett bord för sig själv.
Ett klassiskt exempel på självanslutning finns i en tabell för anställda. I en sådan tabell kan en anställd rapportera till en annan anställd. Därför kan du använda en självanslutning för att gå med i tabellen i kolumnen för anställd-ID och chefs-ID.
Anta att vi har följande tabell:
+--------------+-------------+------------+-------------+ | EmployeeId | FirstName | LastName | ReportsTo | |--------------+-------------+------------+-------------| | 1 | Homer | Connery | NULL | | 2 | Bart | Pitt | 1 | | 3 | Maggie | Griffin | 1 | | 4 | Peter | Farnsworth | 2 | | 5 | Marge | Morrison | NULL | | 6 | Lisa | Batch | 5 | | 7 | Dave | Zuckerberg | 6 | | 8 | Vlad | Cook | 7 | +--------------+-------------+------------+-------------+
Vi kan göra en självanslutning på det här bordet för att returnera alla anställda och deras chefer.
SELECT
CONCAT(e1.FirstName, ' ', e1.LastName) AS Employee,
CONCAT(e2.FirstName, ' ', e2.LastName) AS Manager
FROM Employees e1
LEFT JOIN Employees e2
ON e1.ReportsTo = e2.EmployeeId;
Resultat:
+------------------+-----------------+ | Employee | Manager | |------------------+-----------------| | Homer Connery | | | Bart Pitt | Homer Connery | | Maggie Griffin | Homer Connery | | Peter Farnsworth | Bart Pitt | | Marge Morrison | | | Lisa Batch | Marge Morrison | | Dave Zuckerberg | Lisa Batch | | Vlad Cook | Dave Zuckerberg | +------------------+-----------------+
Se SQL Self Join för fler exempel.