- Wat is een Inner Join?
- Wat is een Outer Join?
- Outer joins uitvoeren met het (+) symbool
Zoals vrijwel alle relationele databases, staat Oracle toe dat query's worden gegenereerd die combineren of JOIN
rijen uit twee of meer tabellen om de uiteindelijke resultaatset te maken. Hoewel er talloze typen zijn van de joins die kunnen worden uitgevoerd, zijn de meest voorkomende de INNER JOIN
en de OUTER JOIN
.
In deze tutorial zullen we kort het verschil onderzoeken tussen de INNER
en OUTER JOIN
en bekijk vervolgens de verkorte methode die Oracle biedt voor het uitvoeren van OUTER JOINS
specifiek met behulp van de +
operatorsymbool.
Wat is een Inner Join?
Een INNER JOIN
in een relationele database is simpelweg het samenvoegen van twee of meer tabellen waarbij het resultaat alleen gegevens zal bevatten die aan alle samenvoegvoorwaarden voldeden .
Hier hebben we bijvoorbeeld een eenvoudige library
schema met twee tabellen:books
en languages
. De languages
tabel is slechts een lijst met mogelijke taalnamen en een unieke taal id
:
SELECT * FROM library.languages;
id name
1 English
2 French
3 German
4 Mandarin
5 Spanish
6 Arabic
7 Japanese
8 Russian
9 Greek
10 Italian
Ondertussen zijn onze books
tabel heeft een language_id
rij die voor de meeste, maar niet alle, boeken gewoon de language_id
. bevat geassocieerd met de oorspronkelijke taal van het boek:
SELECT * FROM
books
ORDER BY
id
FETCH FIRST 10 ROWS ONLY;
id title author year_published language_id
1 In Search of Lost Time Marcel Proust 1913 2
2 Ulysses James Joyce 1922 1
3 Don Quixote Miguel de Cervantes 1605 5
4 Moby Dick Herman Melville 1851 1
5 Hamlet William Shakespeare 1601 (null)
6 War and Peace Leo Tolstoy 1869 8
7 The Odyssey Homer -700 9
8 The Great Gatsby F. Scott Fitzgerald 1925 1
9 The Divine Comedy Dante Alighieri 1472 10
10 Madame Bovary Gustave Flaubert 1857 2
In veel gevallen willen we misschien een INNER JOIN
van de books
en languages
tabellen dus in plaats van de betekenisloze language_id
. te bekijken waarde van elk boek, kunnen we daadwerkelijk de language name
zien in plaats daarvan.
SELECT
b.id,
b.title,
b.author,
b.year_published,
l.name language
FROM
books b
INNER JOIN
library.languages l
ON
b.language_id = l.id
ORDER BY
b.id
FETCH FIRST 10 ROWS ONLY;
id title author year_published language
1 In Search of Lost Time Marcel Proust 1913 French
2 Ulysses James Joyce 1922 English
3 Don Quixote Miguel de Cervantes 1605 Spanish
4 Moby Dick Herman Melville 1851 English
6 War and Peace Leo Tolstoy 1869 Russian
7 The Odyssey Homer -700 Greek
8 The Great Gatsby F. Scott Fitzgerald 1925 English
9 The Divine Comedy Dante Alighieri 1472 Italian
10 Madame Bovary Gustave Flaubert 1857 French
11 The Brothers Karamazov Fyodor Dostoyevsky 1880 Russian
Wat hier van cruciaal belang is om op te merken, is dat onze resultatenset iets anders was in de bovenstaande twee zoekopdrachten. In de eerste hebben we gewoon de eerste 10
. vermeld boeken, maar in de INNER JOIN
query retourneren we alleen resultaten die aan alle voorwaarden van beide tabellen voldoen. Om deze reden is het record van Hamlet
(met een language_id
waarde van null
of leeg) wordt genegeerd en niet geretourneerd in het resultaat van onze INNER JOIN
.
Wat is een Outer Join?
In plaats van uitsluitend resultaten te retourneren die voldoen aan alle deelnamevoorwaarden van een INNER JOIN
, een OUTER JOIN
geeft niet alleen resultaten die aan alle voorwaarden voldoen, maar ook retourneert rijen uit één tabel die niet aan de voorwaarde voldeden. De tabel die wordt gekozen voor deze "omzeiling" van voorwaardelijke vereisten wordt bepaald door de directionaliteit of "kant" van de join, meestal aangeduid als LEFT
of RIGHT
buitenste joins.
Bij het definiëren van een kant aan je OUTER JOIN
, specificeert u welke tabel altijd zijn rij zal retourneren, zelfs als de tegengestelde tabel aan de andere kant van de join ontbreekt of null
waarden als onderdeel van de samenvoegingsvoorwaarde.
Daarom, als we dezelfde basis JOIN
uitvoeren, zoals hierboven om books
op te halen en language names
, weten we dat onze books
tabel moet altijd gegevens retourneren, dus onze JOIN
kant moet "wijzen naar" onze books
tabel, waardoor de languages
tafel de OUTER
tabel die we eraan koppelen.
Om dit te bereiken, veranderen we eenvoudig:
books b INNER JOIN library.languages l
…naar dit:
books b LEFT OUTER JOIN library.languages l
De hele query en resultatenset zien er dus bijna identiek uit als de INNER JOIN
behalve die kleine wijziging:
SELECT
b.id,
b.title,
b.author,
b.year_published,
l.name language
FROM
books b
LEFT OUTER JOIN
library.languages l
ON
b.language_id = l.id
ORDER BY
b.id
FETCH FIRST 10 ROWS ONLY;
id title author year_published language
1 In Search of Lost Time Marcel Proust 1913 French
2 Ulysses James Joyce 1922 English
3 Don Quixote Miguel de Cervantes 1605 Spanish
4 Moby Dick Herman Melville 1851 English
5 Hamlet William Shakespeare 1601 (null)
6 War and Peace Leo Tolstoy 1869 Russian
7 The Odyssey Homer -700 Greek
8 The Great Gatsby F. Scott Fitzgerald 1925 English
9 The Divine Comedy Dante Alighieri 1472 Italian
10 Madame Bovary Gustave Flaubert 1857 French
Zoals verwacht, met behulp van een LEFT OUTER JOIN
in plaats van de vorige INNER JOIN
, we krijgen het beste van twee werelden:we slaan geen books
over records (zoals Hamlet
) simpelweg omdat de language_id
waarde is null
voor dat record, maar voor alle records waar language_id
bestaat, krijgen we de mooi opgemaakte language name
verkregen uit onze languages
tafel.
Outer joins uitvoeren met het (+) symbool
Zoals aangegeven in de officiële documentatie, biedt Oracle een speciale outer join operator
(de +
symbool) dat een afkorting is voor het uitvoeren van OUTER JOINS
.
In de praktijk is de +
symbool wordt direct in de voorwaardelijke . geplaatst statement en aan de zijkant van de optionele tabel (degene die leeg of null
mag bevatten) waarden binnen de voorwaardelijke).
Daarom kunnen we onze bovenstaande LEFT OUTER JOIN
. opnieuw herschrijven statement met de +
operator als volgt:
SELECT
b.id,
b.title,
b.author,
b.year_published,
l.name language
FROM
books b,
library.languages l
WHERE
l.id (+)= b.language_id
ORDER BY
b.id
FETCH FIRST 10 ROWS ONLY;
De resultaten zijn hetzelfde als de standaard LEFT OUTER JOIN
voorbeeld hierboven, dus we zullen ze hier niet opnemen. Er is echter één cruciaal aspect om op te merken over de syntaxis met behulp van de +
operator voor OUTER JOINS
.
De +
operator moet staan aan de linkerkant van de voorwaardelijke (links van de is gelijk aan =
teken). Daarom, in dit geval, omdat we ervoor willen zorgen dat onze languages
table is de optionele tabel die null
kan retourneren waarden tijdens deze vergelijking hebben we de volgorde van de tabellen in deze voorwaardelijke verwisseld, dus languages
is aan de linkerkant (en is optioneel) terwijl books
is aan de rechterkant.
Ten slotte, vanwege deze herschikking van de tafelzijden in de voorwaardelijke bij gebruik van de +
operator, het is belangrijk om te beseffen dat het bovenstaande simpelweg een afkorting is voor een RIGHT OUTER JOIN
. Dit betekent dat dit fragment van de zoekopdracht:
FROM
books b,
library.languages l
WHERE
l.id (+)= b.language_id
...is in feite identiek aan dit:
FROM
library.languages l
RIGHT OUTER JOIN
books b
ON
b.language_id = l.id