sql >> Database >  >> RDS >> Database

Handleiding voor SQL Joins

Bij een SQL-join voert u een query uit die meerdere tabellen samenvoegt.

Deze zelfstudie over SQL-joins geeft basisvoorbeelden van SQL-joins, evenals een inleiding tot de verschillende typen joins.

SQL-deelnametypes

De ANSI SQL-standaard specificeert vijf typen joins, zoals vermeld in de volgende tabel.

Aanmeldtype Beschrijving

INNER JOIN
Retourneert rijen als er in beide tabellen ten minste één rij is die overeenkomt met de voorwaarde voor samenvoegen.

LEFT OUTER JOIN
of
LEFT JOIN
Retourneert rijen met gegevens in de linkertabel (links van de JOIN zoekwoord), zelfs als er geen overeenkomende rijen in de juiste tabel staan.

RIGHT OUTER JOIN
of
RIGHT JOIN
Retourneert rijen met gegevens in de rechtertabel (rechts van de JOIN zoekwoord), zelfs als er geen overeenkomende rijen in de linkertabel zijn.

FULL OUTER JOIN
of
FULL JOIN
Retourneert alle rijen, zolang er overeenkomende gegevens in een van de tabellen zijn.
CROSS JOIN Retourneert rijen die elke rij uit de eerste tabel combineren met elke rij uit de tweede tabel.

Er zijn ook andere termen voor verschillende samenvoegbewerkingen, zoals de volgende:

Deelnemen Beschrijving
Zelf lid worden Als een tafel zich bij zichzelf voegt.
Natuurlijke deelname Een impliciete join gebaseerd op de gemeenschappelijke kolommen in de twee tabellen die worden samengevoegd.
Equi-join Een join die alleen gelijkheidsvergelijkingen bevat in het join-predikaat.

SQL Join-syntaxis

Innerlijke joins kunnen worden opgegeven in de FROM of WHERE clausules. Outer-joins en cross-joins kunnen worden gespecificeerd in de FROM alleen clausule.

Een SQL-join maken in de FROM clausule, doe zoiets als dit:

SELECT *
FROM Table1 < JoinType > Table2 [ ON ( JoinCondition ) ]

Waar JoinType specificeert wat voor soort join wordt uitgevoerd, en JoinCondition definieert het predikaat dat moet worden geëvalueerd voor elk paar samengevoegde rijen.

Een join specificeren in de WHERE clausule, doe zoiets als dit:

SELECT *
FROM Table1, Table2 [ WHERE ( JoinCondition ) ]

Nogmaals, JoinCondition definieert het predikaat dat moet worden geëvalueerd voor elk paar samengevoegde rijen.

Ook alles tussen vierkante haken ([] ) is optioneel.

Voorbeeldtabellen voor de voorbeelden in deze zelfstudie

De meeste voorbeelden in deze tutorial voeren samenvoegingen uit tegen de volgende twee tabellen.

De PetTypes tafel:

+-------------+-----------+
| PetTypeId   | PetType   |
|-------------+-----------|
| 1           | Bird      |
| 2           | Cat       |
| 3           | Dog       |
| 4           | Rabbit    |
+-------------+-----------+
(4 rows affected)

De Pets tafel:

+---------+-------------+-----------+-----------+------------+
| 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)

De innerlijke verbinding

De SQL INNER JOIN retourneert rijen wanneer er in beide tabellen ten minste één rij is die overeenkomt met de join-voorwaarde.

SELECT
    Pets.PetName,
    PetTypes.PetType
FROM Pets
INNER JOIN PetTypes
ON Pets.PetTypeId = PetTypes.PetTypeId;

Resultaat:

-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+
(8 rows affected)

Een inner join specificeren in de FROM clausule gebruiken we INNER JOIN . We gebruiken ook de ON trefwoord om het predikaat te definiëren dat moet worden geëvalueerd voor elk paar samengevoegde rijen.

Ongeacht het type join, kwalificeren we onze kolomnamen met de tabelnamen. De reden dat we dit doen is om onduidelijkheid over de kolomnamen tussen de tabellen te voorkomen. Beide tabellen kunnen kolommen met dezelfde naam hebben (zoals in ons voorbeeld), en in dergelijke gevallen weet het DBMS niet naar welke kolom u verwijst. Door de kolomnamen vooraf te laten gaan door hun tabelnamen zorgt u ervoor dat u naar de juiste kolom verwijst en voorkomt u fouten die zouden kunnen voortvloeien uit onduidelijkheid over de kolom waarnaar u verwijst.

In dit voorbeeld hebben beide tabellen een PetTypeId kolom. De Pets.PetTypeId kolom is een refererende sleutel voor de PetTypes.PetTypeId kolom, wat de primaire sleutel is voor die tabel.

In dit voorbeeld kunnen we zien dat alle huisdieren worden geretourneerd, maar niet alle soorten huisdieren. Er zijn geen konijnen in de Pets tabel, en dus de Rabbits huisdiertype wordt niet geretourneerd.

De reden waarom de Rabbits type niet wordt geretourneerd, is omdat de INNER JOIN retourneert alleen rijen als er in beide tabellen ten minste één rij is die overeenkomt met de join-voorwaarde. In dit geval, Rabbits staat slechts in één tabel (de PetTypes tafel).

Houd er rekening mee dat het join-type optioneel is. Daarom kunt u bij de meeste (zo niet alle) DBMS'en de INNER . weglaten trefwoord. Wanneer u dit weglaat (d.w.z. alleen JOIN specificeren) ), wordt aangenomen dat het een inner join is.

Daarom zouden we het bovenstaande voorbeeld hiernaar kunnen herschrijven:

SELECT
    Pets.PetName,
    PetTypes.PetType
FROM Pets
JOIN PetTypes
ON Pets.PetTypeId = PetTypes.PetTypeId;

Ook, zoals bij elke SQL-instructie, is de FROM clausule kan op één hele regel staan ​​als je dat liever hebt:

SELECT
    Pets.PetName,
    PetTypes.PetType
FROM Pets JOIN PetTypes ON Pets.PetTypeId = PetTypes.PetTypeId;

Aliasen

Het is gebruikelijk om tabelaliassen te gebruiken bij het uitvoeren van SQL-joins. Aliassen helpen om de code beknopter en gemakkelijker te lezen te maken.

Daarom zouden we het vorige voorbeeld in dit kunnen veranderen:

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p INNER JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;

Resultaat:

-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+
(8 rows affected)

De Equi-Join

De bovenstaande join kan ook worden aangeduid als een equi-join . Een equi-join is een join die alleen gelijkheidsvergelijkingen bevat in het join-predikaat.

Een andere manier om de bovenstaande join te schrijven is als volgt:

SELECT
    p.PetName,
    pt.PetType
FROM 
    Pets p, 
    PetTypes pt
WHERE p.PetTypeId = pt.PetTypeId;

Resultaat:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+

Dit is een voorbeeld van het specificeren van een inner join in de WHERE clausule. We hebben gewoon een door komma's gescheiden lijst van de tabellen gegeven en vervolgens een WHERE voorwaarde. Als we de WHERE . hadden weggelaten voorwaarde, zouden we zijn geëindigd met een CROSS JOIN .

Veel beginners vinden de bovenstaande syntaxis veel gemakkelijker te begrijpen dan de INNER JOIN syntaxis. Voel je vrij om deze syntaxis te gebruiken als je dat liever hebt, maar houd er rekening mee dat de meeste SQL-professionals de voorkeur geven aan de INNER JOIN syntaxis van het vorige voorbeeld.

Zie SQL Inner Join voor meer voorbeelden, waaronder een inner join die 3 tabellen samenvoegt.

De juiste deelname

Ook bekend als de RIGHT OUTER JOIN , de RIGHT JOIN retourneert rijen met gegevens in de juiste tabel (rechts van de JOIN zoekwoord), zelfs als er geen overeenkomende rijen in de linkertabel zijn.

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
RIGHT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;

Resultaat:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Tweet     | Bird      |
| Fluffy    | Cat       |
| Scratch   | Cat       |
| Meow      | Cat       |
| Fetch     | Dog       |
| Wag       | Dog       |
| Fluffy    | Dog       |
| Bark      | Dog       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

In dit geval kregen we een extra PetType waarde – Rabbit – ook al is er geen huisdier in de Pets tafel van dat type. Dit resulteert in een NULL waarde in de PetName kolom tegen Rabbit .

Zie SQL Right Join voor meer voorbeelden, waaronder een Right Join die 3 tabellen samenvoegt.

The Left Join

Ook bekend als de LEFT OUTER JOIN , de SQL LEFT JOIN retourneert rijen met gegevens in de linkertabel (links van de JOIN zoekwoord), zelfs als er geen overeenkomende rijen in de juiste tabel staan.

Dit is het tegenovergestelde van de RIGHT JOIN .

Als we het vorige voorbeeld wijzigen om een ​​left join te gebruiken, krijgen we het volgende resultaat.

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
LEFT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;

Resultaat:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+
(8 rows affected)

In dit specifieke geval zijn onze resultaten hetzelfde als bij de inner join.

Als we echter de tafelvolgorde omwisselen in onze FROM clausule, krijgen we een vergelijkbaar resultaat als de juiste join in het vorige voorbeeld.

SELECT 
    p.PetName,
    pt.PetType
FROM PetTypes pt
LEFT JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;

Resultaat:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Tweet     | Bird      |
| Fluffy    | Cat       |
| Scratch   | Cat       |
| Meow      | Cat       |
| Fetch     | Dog       |
| Wag       | Dog       |
| Fluffy    | Dog       |
| Bark      | Dog       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

U kunt dus zien dat elk resulterend verschil tussen de linker en rechter joins uitsluitend afhangt van de volgorde van de kolommen in de FROM clausule.

Zie SQL Left Join voor meer voorbeelden, waaronder een left join die 3 tabellen samenvoegt.

De volledige deelname

De SQL FULL JOIN (of FULL OUTER JOIN ) geeft alle rijen terug, zolang er overeenkomende gegevens in een van de tabellen zijn.

Met andere woorden, het is alsof je zowel een linker- als een rechterjoin in één join hebt.

Hier is een voorbeeld van een volledige deelname.

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
FULL JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;

Resultaat:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

Dit geeft hetzelfde resultaat als met de rechter join, maar het zou een ander resultaat hebben opgeleverd als er een rij in de linkertabel was geweest die geen overeenkomstige waarde had in de rechtertabel.

Laten we de tabelnamen omwisselen en het opnieuw uitvoeren.

SELECT 
    p.PetName,
    pt.PetType
FROM PetTypes pt
FULL JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;

Resultaat:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Tweet     | Bird      |
| Fluffy    | Cat       |
| Scratch   | Cat       |
| Meow      | Cat       |
| Fetch     | Dog       |
| Wag       | Dog       |
| Fluffy    | Dog       |
| Bark      | Dog       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

Zelfde resultaat.

Zie SQL Full Join voor meer voorbeelden, waaronder een volledige join die 3 tabellen samenvoegt.

The Cross Join

De SQL CROSS JOIN retourneert rijen die elke rij uit de eerste tabel combineren met elke rij uit de tweede tabel.

Met andere woorden, het retourneert het Cartesiaanse product van rijen uit tabellen in de join.

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
CROSS JOIN PetTypes pt;

Resultaat:

+-----------+-----------+
| 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)

Zoals je je waarschijnlijk kunt voorstellen, kan dit erg gevaarlijk zijn als je het tegen de verkeerde tafels uitvoert.

Het is hetzelfde als dit doen:

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p, PetTypes pt;

U kunt een WHERE . toevoegen clausule toe aan een cross join, waardoor het een inner join wordt.

Zoals dit:

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
CROSS JOIN PetTypes pt
WHERE p.PetTypeId = pt.PetTypeId;

Resultaat:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+
(8 rows affected)

Zie SQL Cross Join voor meer voorbeelden.

The Natural Join

De SQL NATURAL JOIN is een type equi-join waarbij het join-predikaat impliciet ontstaat door alle kolommen in beide tabellen met dezelfde kolomnaam in de samengevoegde tabellen te vergelijken.

De resultatenset bevat slechts één kolom voor elk paar gelijknamige kolommen. Als er geen kolommen met dezelfde namen worden gevonden, is het resultaat een cross join.

SELECT 
    Pets.PetName,
    PetTypes.PetType
FROM Pets NATURAL JOIN PetTypes;

Resultaat:

petname | pettype 
---------+---------
 Fluffy  | Cat
 Fetch   | Dog
 Scratch | Cat
 Wag     | Dog
 Tweet   | Bird
 Fluffy  | Dog
 Bark    | Dog
 Meow    | Cat
(8 rows)

Eigenlijk is de natuurlijke join niet echt een join-type, zoals wordt overwogen door de ANSI-standaard. Het is een trefwoord dat u optioneel kunt invoegen om van de join een natuurlijke join te maken.

Daarom zouden we het bovenstaande voorbeeld kunnen veranderen in NATURAL INNER JOIN als we wilden:

SELECT 
    Pets.PetName,
    PetTypes.PetType
FROM Pets NATURAL INNER JOIN PetTypes;

Zoals eerder vermeld, zijn inner joins het standaard jointype, dus als u het jointype weglaat (bijv. INNER , LEFT , RIGHT , etc), dan wordt het behandeld als een inner join.

Als de opmaak van deze resultaten er anders uitziet dan de vorige resultaten, komt dat omdat ik naar PostgreSQL moest springen om deze query uit te voeren. Ik heb de vorige voorbeelden in SQL Server uitgevoerd, maar SQL Server ondersteunt de natuurlijke join niet.

Zie SQL Natural Join voor meer voorbeelden, waaronder een natuurlijke join die 3 tabellen samenvoegt.

The Self Join

De SQL SELF JOIN voegt zich bij een tafel bij zichzelf.

Een klassiek voorbeeld van een self-join is in een Employees-tabel. In zo'n tabel kan de ene medewerker zich melden bij een andere medewerker. Daarom kunt u een self-join gebruiken om deel te nemen aan de tabel in de kolom met werknemers-ID's en kolom met manager-ID's.

Stel dat we de volgende tabel hebben:

+--------------+-------------+------------+-------------+
| 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           |
+--------------+-------------+------------+-------------+

We kunnen een self-join doen op deze tafel om alle medewerkers en hun managers terug te sturen.

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;

Resultaat:

+------------------+-----------------+
| 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 |
+------------------+-----------------+

Zie SQL Self Join voor meer voorbeelden.


  1. ORA-01036:ongeldige variabele naam/nummer bij het uitvoeren van een query via C#

  2. Interviewvragen voor data-ingenieurs met Python

  3. Meest populaire databasebeheersystemen ter wereld

  4. Hoe maak je een SQL-weergave met SQLAlchemy?