sql >> Database teknologi >  >> RDS >> Database

Selvstudium til SQL joins

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.


  1. Hvordan opretter man forbindelse til MySQL på Amazon EC2 fra Linux / Mac?

  2. Oracle sletter rækker fra flere tabeller

  3. Hvordan reparerer jeg en InnoDB-tabel?

  4. Sådan oprettes fremmednøglebegrænsning på flere kolonner i SQL Server - SQL Server / TSQL vejledning del 67