- Hvad er en indre forbindelse?
- Hvad er en Outer Join?
- Udførelse af ydre sammenføjninger ved hjælp af (+)-symbolet
Som stort set alle relationelle databaser tillader Oracle, at der genereres forespørgsler, der kombinerer eller JOIN
rækker fra to eller flere tabeller for at skabe det endelige resultatsæt. Mens der er adskillige typer af joinforbindelser, der kan udføres, er de mest almindelige INNER JOIN
og OUTER JOIN
.
I denne øvelse vil vi kort udforske forskellen mellem INNER
og OUTER JOIN
og undersøg derefter den stenografiske metode Oracle giver til at udføre OUTER JOINS
specifikt ved at bruge +
operatørsymbol.
Hvad er en indre forbindelse?
En INNER JOIN
i en relationsdatabase er blot sammenføjningen af to eller flere tabeller, hvor resultatet kun vil indeholde data, der opfyldte alle sammenføjningsbetingelser .
For eksempel har vi her et grundlæggende library
skema med to tabeller:books
og languages
. languages
tabel er blot en liste over mulige sprognavne og et unikt sprog 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
I mellemtiden er vores books
tabellen har et language_id
række, som for de fleste, men ikke alle, bøger blot indeholder language_id
forbundet med bogens originale udgivne sprog:
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
I mange tilfælde ønsker vi måske at udføre en INNER JOIN
af books
og languages
tabeller i stedet for at se det meningsløse language_id
værdien af hver bog, kan vi faktisk se language name
i stedet.
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
Det, der er vigtigt at bemærke her, er, at vores resultatsæt var lidt anderledes i de to ovenstående forespørgsler. I den første listede vi simpelthen de første 10
bøger, men i INNER JOIN
forespørgsel, vi returnerer kun resultater, der opfylder alle betingelser fra begge tabeller. Af denne grund er registreringen af Hamlet
(som har et language_id
værdien af null
eller tom) ignoreres og returneres ikke i resultatet af vores INNER JOIN
.
Hvad er en Outer Join?
I stedet for udelukkende at returnere resultater, der opfylder alle deltagelsesbetingelser for en INNER JOIN
, en OUTER JOIN
returnerer ikke kun resultater, der opfylder alle betingelser, men også returnerer rækker fra én tabel, som ikke opfyldte betingelsen. Tabellen, der vælges til denne "bypass" af betingede krav, bestemmes af retningsbestemtheden eller "siden" af joinforbindelsen, typisk omtalt som LEFT
eller RIGHT
ydre sammenføjninger.
Når du definerer en side til din OUTER JOIN
, angiver du, hvilken tabel der altid vil returnere sin række, selvom den modsatte tabellen på den anden side af joinforbindelsen mangler eller null
værdier som en del af sammenføjningsbetingelsen.
Derfor, hvis vi udfører den samme grundlæggende JOIN
som ovenfor for at hente books
og language names
, vi ved, at vores books
tabel skal altid returnere data, så vores JOIN
side skal "pege mod" vores books
tabel, hvilket gør languages
tabel OUTER
bord, vi vedhæfter til det.
For at opnå dette ændrer vi blot:
books b INNER JOIN library.languages l
…til dette:
books b LEFT OUTER JOIN library.languages l
Således ser hele forespørgslen og resultatsættet næsten identisk ud med INNER JOIN
bortset fra den mindre ændring:
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
Som forventet ved at bruge en LEFT OUTER JOIN
i stedet for den tidligere INNER JOIN
, vi får det bedste fra begge verdener:Vi springer ikke over nogen books
poster (såsom Hamlet
) simpelthen fordi language_id
værdien er null
for den post, men for alle poster, hvor language_id
eksisterer, får vi det pænt formaterede language name
hentet fra vores languages
tabel.
Udførelse af ydre sammenføjninger ved hjælp af (+) symbolet
Som angivet i den officielle dokumentation tilbyder Oracle en speciel outer join operator
(+
symbol), der er en forkortelse for at udføre OUTER JOINS
.
I praksis er +
symbolet er placeret direkte i den betingede sætning og på siden af den valgfri tabel (den der må indeholde tom eller null
værdier inden for den betingede).
Derfor kan vi igen omskrive vores ovenstående LEFT OUTER JOIN
sætning ved hjælp af +
operatør som sådan:
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;
Resultaterne er de samme som standard LEFT OUTER JOIN
eksemplet ovenfor, så vi vil ikke inkludere dem her. Der er dog et kritisk aspekt at bemærke om syntaksen ved hjælp af +
operatør for OUTER JOINS
.
+
operatør skal være på venstre side af den betingede (venstre for er lig med =
skilt). Derfor, i dette tilfælde, fordi vi ønsker at sikre, at vores languages
tabel er den valgfri tabel, der kan returnere null
værdier under denne sammenligning, byttede vi rækkefølgen af tabellerne i denne betingede, så languages
er til venstre (og er valgfrit), mens books
er til højre.
Til sidst, på grund af denne omarrangering af tabelsiderne i den betingede, når du bruger +
operatør, er det vigtigt at indse, at ovenstående blot er en forkortelse for en RIGHT OUTER JOIN
. Det betyder, at dette uddrag af forespørgslen:
FROM
books b,
library.languages l
WHERE
l.id (+)= b.language_id
…er faktisk identisk med denne:
FROM
library.languages l
RIGHT OUTER JOIN
books b
ON
b.language_id = l.id