En SQL-join er, hvor du kører en forespørgsel, der forbinder flere tabeller.
Denne SQL joins tutorial præsenterer grundlæggende eksempler på SQL joins, samt en introduktion til de forskellige jointyper.
SQL-tilslutningstyper
ANSI SQL-standarden specificerer fem typer joinforbindelser som angivet i følgende tabel.
Join Type | Beskrivelse |
---|---|
INNER JOIN | Returnerer rækker, når der er mindst én række i begge tabeller, der matcher sammenføjningsbetingelsen. |
LEFT OUTER JOIN eller LEFT JOIN | Returnerer rækker, der har data i den venstre tabel (til venstre for JOIN søgeord), selvom der ikke er nogen matchende rækker i den højre tabel. |
RIGHT OUTER JOIN eller RIGHT JOIN | Returnerer rækker, der har data i den højre tabel (til højre for JOIN søgeord), selvom der ikke er nogen matchende rækker i den venstre tabel. |
FULL OUTER JOIN eller FULL JOIN | Returnerer alle rækker, så længe der er matchende data i en af tabellerne. |
CROSS JOIN | Returnerer rækker, der kombinerer hver række fra den første tabel med hver række fra den anden tabel. |
Der er også andre vilkår for forskellige join-operationer, såsom følgende:
Deltag | Beskrivelse |
---|---|
Tilmeld dig selv | Når et bord slutter sig til sig selv. |
Naturlig tilslutning | En implicit joinforbindelse baseret på de fælles kolonner i de to tabeller, der forbindes. |
Equi-join | En join, der kun indeholder lighedssammenligninger i join-prædikatet. |
SQL Join Syntax
Indre joinforbindelser kan angives i enten FROM
eller WHERE
klausuler. Ydre sammenføjninger og krydsforbindelser kan angives i FROM
kun klausul.
For at oprette en SQL join i FROM
klausul, gør noget som dette:
SELECT *
FROM Table1 < JoinType > Table2 [ ON ( JoinCondition ) ]
Hvor JoinType
angiver, hvilken slags joinforbindelse der udføres, og JoinCondition
definerer prædikatet, der skal evalueres for hvert par af sammenføjede rækker.
For at angive en joinforbindelse i WHERE
klausul, gør noget som dette:
SELECT *
FROM Table1, Table2 [ WHERE ( JoinCondition ) ]
Igen, JoinCondition
definerer prædikatet, der skal evalueres for hvert par af sammenføjede rækker.
Alt er også omgivet af firkantede parenteser ([]
) er valgfri.
Eksempler på tabeller til eksemplerne i dette selvstudie
De fleste af eksemplerne i denne øvelse udfører joinforbindelser mod de følgende to tabeller.
PetTypes
tabel:
+-------------+------------+| PetTypeId | PetType ||-------------+---------|| 1 | Fugl || 2 | Kat || 3 | Hund || 4 | Kanin |+-------------+------------+(4 rækker påvirket)
Pets
tabel:
+---------+----------------------- --+------------+| PetId | PetTypeId | OwnerId | Kæledyrsnavn | DOB ||--------+------------------------ +------------|| 1 | 2 | 3 | Fluffy | 20-11-2020 || 2 | 3 | 3 | Hent | 2019-08-16 || 3 | 2 | 2 | Ridse | 2018-10-01 || 4 | 3 | 3 | Wag | 15-03-2020 || 5 | 1 | 1 | Tweet | 28-11-2020 || 6 | 3 | 4 | Fluffy | 2020-09-17 || 7 | 3 | 2 | Bark | NULL || 8 | 2 | 4 | Mjav | NULL |+----------------------------- +------------+(8 rækker påvirket)
Det indre led
SQL INNER JOIN
returnerer rækker, når der er mindst én række i begge tabeller, der matcher join-betingelsen.
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets
INNER JOIN PetTypes
ON Pets.PetTypeId = PetTypes.PetTypeId;
Resultat:
-----------+-----------+| Kæledyrsnavn | PetType ||-----------+--------|| Fluffy | Kat || Hent | Hund || Ridse | Kat || Wag | Hund || Tweet | Fugl || Fluffy | Hund || Bark | Hund || Mjav | Kat |+-----------+-----------+(8 rækker påvirket)
For at angive en indre joinforbindelse i FROM
klausul, bruger vi INNER JOIN
. Vi bruger også ON
nøgleord for at definere prædikatet, der skal evalueres for hvert par af sammenføjede rækker.
Uanset jointype kvalificerer vi vores kolonnenavne med tabelnavnene. Grunden til, at vi gør dette, er for at undgå uklarhed med hensyn til kolonnenavnene mellem tabellerne. Begge tabeller kunne have kolonner med samme navn (som i vores eksempel), og i sådanne tilfælde ved DBMS ikke, hvilken kolonne du henviser til. Ved at præfikse kolonnenavnene med deres tabelnavne sikrer du, at du refererer til den højre kolonne, og forhindrer fejl, der kan skyldes uklarhed om, hvilken kolonne du henviser til.
I dette eksempel har begge tabeller et PetTypeId
kolonne. Pets.PetTypeId
kolonnen er en fremmednøgle til PetTypes.PetTypeId
kolonne, som er den primære nøgle til den pågældende tabel.
I dette eksempel kan vi se, at alle kæledyr returneres, men ikke alle kæledyrstyper returneres. Der er ingen kaniner i Pets
tabellen, og så Rabbits
kæledyrstype returneres ikke.
Årsagen til Rabbits
type ikke returneres, fordi INNER JOIN
returnerer kun rækker, når der er mindst én række i begge tabeller, der matcher join-betingelsen. I dette tilfælde Rabbits
er kun i én tabel (PetTypes
tabel).
Bemærk, at jointypen er valgfri. Derfor tillader de fleste (hvis ikke alle) DBMS'er dig at udelade INNER
søgeord. Når du udelader dette (dvs. kun specificer JOIN
). ), antages det at være en indre sammenføjning.
Derfor kunne vi omskrive ovenstående eksempel til dette:
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets
JOIN PetTypes
ON Pets.PetTypeId = PetTypes.PetTypeId;
Ligeledes, som med enhver SQL-sætning, er FROM
klausul kan være på en hel linje, hvis du foretrækker:
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets JOIN PetTypes ON Pets.PetTypeId = PetTypes.PetTypeId;
Aliaser
Det er almindelig praksis at bruge tabelaliasser, når du udfører SQL-sammenføjninger. Aliaser hjælper med at gøre koden mere kortfattet og lettere at læse.
Derfor kunne vi ændre det forrige eksempel til dette:
SELECT
p.PetName,
pt.PetType
FROM Pets p INNER JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Resultat:
-----------+-----------+| Kæledyrsnavn | PetType ||-----------+--------|| Fluffy | Kat || Hent | Hund || Ridse | Kat || Wag | Hund || Tweet | Fugl || Fluffy | Hund || Bark | Hund || Mjav | Kat |+-----------+-----------+(8 rækker påvirket)
Equi-Join
Ovenstående joinforbindelse kan også omtales som en equi-join . En equi-join er en join, der kun indeholder lighedssammenligninger i join-prædikatet.
En anden måde at skrive ovenstående join på er sådan her:
SELECT
p.PetName,
pt.PetType
FROM
Pets p,
PetTypes pt
WHERE p.PetTypeId = pt.PetTypeId;
Resultat:
+-------+------------+| Kæledyrsnavn | PetType ||-----------+--------|| Fluffy | Kat || Hent | Hund || Ridse | Kat || Wag | Hund || Tweet | Fugl || Fluffy | Hund || Bark | Hund || Mjav | Kat |+-----------+-----------+
Dette er et eksempel på at angive en indre joinforbindelse i WHERE
klausul. Vi leverede simpelthen en kommasepareret liste over tabellerne og derefter en WHERE
tilstand. Hvis vi havde udeladt WHERE
betingelse, ville vi have endt med en CROSS JOIN
.
Mange begyndere finder ovenstående syntaks meget lettere at forstå end INNER JOIN
syntaks. Du er velkommen til at bruge denne syntaks, hvis du foretrækker det, men vær opmærksom på, at de fleste SQL-professionelle foretrækker at bruge INNER JOIN
syntaks fra det forrige eksempel.
Se SQL Inner Join for flere eksempler, inklusive en indre join, der forbinder 3 tabeller.
Den rigtige tilslutning
Også kendt som RIGHT OUTER JOIN
, RIGHT JOIN
returnerer rækker, der har data i den højre tabel (til højre for JOIN
søgeord), selvom der ikke er nogen matchende rækker i den venstre tabel.
SELECT
p.PetName,
pt.PetType
FROM Pets p
RIGHT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Resultat:
+-------+------------+| Kæledyrsnavn | PetType ||-----------+--------|| Tweet | Fugl || Fluffy | Kat || Ridse | Kat || Mjav | Kat || Hent | Hund || Wag | Hund || Fluffy | Hund || Bark | Hund || NULL | Kanin |+-----------+-----------+(9 rækker påvirket)
I dette tilfælde fik vi en ekstra PetType
værdi – Rabbit
– selvom der ikke er noget kæledyr i Pets
bord af den type. Dette resulterer i en NULL
værdi i PetName
kolonne mod Rabbit
.
Se SQL Right Join for flere eksempler, inklusive en højre join, der forbinder 3 tabeller.
Venstre tilslutter sig
Også kendt som LEFT OUTER JOIN
, SQL'en LEFT JOIN
returnerer rækker, der har data i den venstre tabel (til venstre for JOIN
søgeord), selvom der ikke er nogen matchende rækker i den højre tabel.
Dette er det modsatte af RIGHT JOIN
.
Hvis vi ændrer det forrige eksempel til at bruge en venstre join, får vi følgende resultat.
SELECT
p.PetName,
pt.PetType
FROM Pets p
LEFT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Resultat:
+-------+------------+| Kæledyrsnavn | PetType ||-----------+--------|| Fluffy | Kat || Hent | Hund || Ridse | Kat || Wag | Hund || Tweet | Fugl || Fluffy | Hund || Bark | Hund || Mjav | Kat |+-----------+-----------+(8 rækker påvirket)
I dette særlige tilfælde er vores resultater de samme som med den indre forbindelse.
Men hvis vi bytter bordrækkefølgen rundt i vores FROM
klausul, får vi et resultat svarende til højre join i det forrige eksempel.
SELECT
p.PetName,
pt.PetType
FROM PetTypes pt
LEFT JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;
Resultat:
+-------+------------+| Kæledyrsnavn | PetType ||-----------+--------|| Tweet | Fugl || Fluffy | Kat || Ridse | Kat || Mjav | Kat || Hent | Hund || Wag | Hund || Fluffy | Hund || Bark | Hund || NULL | Kanin |+-----------+-----------+(9 rækker påvirket)
Så du kan se, at enhver resulterende forskel mellem venstre og højre joins udelukkende afhænger af, hvordan du bestiller kolonnerne i FROM
klausul.
Se SQL Left Join for flere eksempler, inklusive en venstre join, der forbinder 3 tabeller.
Fuld tilslutning
SQL'en FULL JOIN
(eller FULL OUTER JOIN
) returnerer alle rækker, så længe der er matchende data i en af tabellerne.
Med andre ord er det ligesom at have både venstre og højre join i én join.
Her er et eksempel på en fuld tilslutning.
SELECT
p.PetName,
pt.PetType
FROM Pets p
FULL JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Resultat:
+-------+------------+| Kæledyrsnavn | PetType ||-----------+--------|| Fluffy | Kat || Hent | Hund || Ridse | Kat || Wag | Hund || Tweet | Fugl || Fluffy | Hund || Bark | Hund || Mjav | Kat || NULL | Kanin |+-----------+-----------+(9 rækker påvirket)
Dette returnerer det samme resultat, som vi fik med den højre join, men det ville have returneret et andet resultat, hvis der havde været en række i den venstre tabel, der ikke havde en tilsvarende værdi i den højre tabel.
Lad os bytte om på tabelnavnene og køre det igen.
SELECT
p.PetName,
pt.PetType
FROM PetTypes pt
FULL JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;
Resultat:
+-------+------------+| Kæledyrsnavn | PetType ||-----------+--------|| Tweet | Fugl || Fluffy | Kat || Ridse | Kat || Mjav | Kat || Hent | Hund || Wag | Hund || Fluffy | Hund || Bark | Hund || NULL | Kanin |+-----------+-----------+(9 rækker påvirket)
Samme resultat.
Se SQL Full Join for flere eksempler, inklusive en fuld join, der forbinder 3 tabeller.
Korset slutter sig til
SQL CROSS JOIN
returnerer rækker, som kombinerer hver række fra den første tabel med hver række fra den anden tabel.
Med andre ord returnerer den det kartesiske produkt af rækker fra tabeller i joinforbindelsen.
SELECT
p.PetName,
pt.PetType
FROM Pets p
CROSS JOIN PetTypes pt;
Resultat:
+-------+------------+| Kæledyrsnavn | PetType ||-----------+--------|| Fluffy | Fugl || Hent | Fugl || Ridse | Fugl || Wag | Fugl || Tweet | Fugl || Fluffy | Fugl || Bark | Fugl || Mjav | Fugl || Fluffy | Kat || Hent | Kat || Ridse | Kat || Wag | Kat || Tweet | Kat || Fluffy | Kat || Bark | Kat || Mjav | Kat || Fluffy | Hund || Hent | Hund || Ridse | Hund || Wag | Hund || Tweet | Hund || Fluffy | Hund || Bark | Hund || Mjav | Hund || Fluffy | Kanin || Hent | Kanin || Ridse | Kanin || Wag | Kanin || Tweet | Kanin || Fluffy | Kanin || Bark | Kanin || Mjav | Kanin |+-----------+-----------+(32 rækker påvirket)
Som du sikkert kan forestille dig, kan dette være meget farligt, hvis du kører det mod de forkerte borde.
Det er det samme som at gøre dette:
SELECT
p.PetName,
pt.PetType
FROM Pets p, PetTypes pt;
Du kan tilføje en WHERE
klausul til en krydssammenføjning, som vil gøre den til en indre sammenføjning.
Sådan:
SELECT
p.PetName,
pt.PetType
FROM Pets p
CROSS JOIN PetTypes pt
WHERE p.PetTypeId = pt.PetTypeId;
Resultat:
+-------+------------+| Kæledyrsnavn | PetType ||-----------+--------|| Fluffy | Kat || Hent | Hund || Ridse | Kat || Wag | Hund || Tweet | Fugl || Fluffy | Hund || Bark | Hund || Mjav | Kat |+-----------+-----------+(8 rækker påvirket)
Se SQL Cross Join for flere eksempler.
The Natural Join
SQL NATURAL JOIN
er en type equi-join, hvor join-prædikatet opstår implicit ved at sammenligne alle kolonner i begge tabeller, der har de samme kolonnenavne i de sammenføjede tabeller.
Resultatsættet indeholder kun én kolonne for hvert par af samme navngivne kolonner. Hvis ingen kolonner med de samme navne findes, vil resultatet være en krydssammenføjning.
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets NATURAL JOIN PetTypes;
Resultat:
kæledyrsnavn | pettype ----------+--------- Fluffy | Cat Fetch | Dog Scratch | Cat Wag | Hund Tweet | Fugl Fluffy | Hundegø | Hunde Mjau | Cat(8 rækker)
Faktisk er den naturlige sammenføjning faktisk ikke en sammenføjningstype, som anset af ANSI-standarden. Det er et nøgleord, som du valgfrit kan indsætte for at gøre joinforbindelsen til en naturlig joinforbindelse.
Derfor kunne vi ændre ovenstående eksempel til NATURAL INNER JOIN
hvis vi ville:
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets NATURAL INNER JOIN PetTypes;
Som tidligere nævnt er indre joinforbindelser standard join-typen, så hvis du udelader join-typen (f.eks. INNER
, LEFT
, RIGHT
osv.), så behandles det som en indre sammenføjning.
Hvis formateringen af disse resultater ser anderledes ud end de tidligere resultater, er det fordi jeg var nødt til at springe over til PostgreSQL for at køre denne forespørgsel. Jeg kørte de tidligere eksempler i SQL Server, men SQL Server understøtter ikke den naturlige joinforbindelse.
Se SQL Natural Join for flere eksempler, inklusive en naturlig join, der forbinder 3 tabeller.
Det selvtilsluttede
SQL SELF JOIN
slutter sig til et bord for sig selv.
Et klassisk eksempel på selvtilslutning er i en medarbejdertabel. I en sådan tabel kan en medarbejder rapportere til en anden medarbejder. Derfor kan du bruge en selvtilslutning til at deltage i tabellen på dens medarbejder-id-kolonne og leder-id-kolonne.
Antag, at vi har følgende tabel:
+--------------+-------------+------------+---- ----------+| Medarbejder-id | Fornavn | Efternavn | RapporterTil ||--------------+-------------+------------+----- --------|| 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 | Kok | 7 |+--------------+-------------+-------------+----- --------+
Vi kan lave en selvtilslutning på dette bord for at returnere alle medarbejdere og deres ledere.
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:
+------------------------+----------------+| Medarbejder | Leder ||----------------+----------------|| 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 for flere eksempler.