sql >> Databasteknik >  >> RDS >> Database

Handledning för SQL-anslutningar

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.


  1. ML{.NET} Introduktion

  2. Utmaningslösningar för nummerseriegenerator – del 5

  3. implodera en lista för användning i en python MySQLDB IN-sats

  4. Oracle:SQL-fråga som returnerar rader med endast numeriska värden