- Vad är en Inner Join?
- Vad är en Outer Join?
- Utföra yttre sammanfogningar med hjälp av (+)-symbolen
Liksom praktiskt taget alla relationsdatabaser tillåter Oracle att frågor genereras som kombinerar eller JOIN
rader från två eller flera tabeller för att skapa den slutliga resultatuppsättningen. Även om det finns många typer av joins som kan utföras är de vanligaste INNER JOIN
och OUTER JOIN
.
I den här handledningen ska vi kort utforska skillnaden mellan INNER
och OUTER JOIN
och undersök sedan förkortningsmetoden Oracle tillhandahåller för att utföra OUTER JOINS
specifikt med hjälp av +
operatörssymbol.
Vad är en Inner Join?
En INNER JOIN
i en relationsdatabas är helt enkelt sammanfogningen av två eller flera tabeller där resultatet endast kommer att innehålla data som uppfyller alla sammanfogningsvillkor .
Till exempel, här har vi ett grundläggande library
schema med två tabeller:books
och languages
. languages
tabellen är bara en lista över möjliga språknamn och ett unikt språk 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
Under tiden våra books
tabellen har ett language_id
rad som för de flesta, men inte alla, böcker helt enkelt innehåller language_id
kopplat till bokens originalspråk:
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 många fall kanske vi vill utföra en INNER JOIN
av books
och languages
tabeller så istället för att se det meningslösa language_id
värdet av varje bok kan vi faktiskt se language name
istället.
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 som är viktigt att notera här är att vår resultatuppsättning var något annorlunda i de två ovanstående frågorna. I den första listade vi helt enkelt de första 10
böcker, men i INNER JOIN
fråga returnerar vi bara resultat som uppfyller alla villkor från båda tabellerna. Av denna anledning, posten för Hamlet
(som har ett language_id
värdet på null
eller tom) ignoreras och returneras inte i resultatet av vår INNER JOIN
.
Vad är en Outer Join?
Istället för att endast returnera resultat som uppfyller alla anslutningsvillkor för en INNER JOIN
, en OUTER JOIN
ger inte bara resultat som uppfyller alla villkor, utan även returnerar rader från en tabell som inte uppfyllde villkoret. Tabellen som väljs för denna "bypass" av villkorliga krav bestäms av riktningen eller "sidan" av kopplingen, vanligtvis kallad LEFT
eller RIGHT
yttre sammanfogningar.
När du definierar en sida till din OUTER JOIN
, anger du vilken tabell som alltid ska returnera sin rad även om den motstående tabellen på andra sidan av kopplingen saknas eller null
värden som en del av sammanfogningsvillkoret.
Därför, om vi utför samma grundläggande JOIN
som ovan för att hämta books
och language names
, vi vet att våra books
Tabellen ska alltid returnera data, så vår JOIN
sidan ska "peka mot" våra books
tabell, vilket gör languages
tabell OUTER
bord vi fäster vid den.
För att åstadkomma detta ändrar vi helt enkelt:
books b INNER JOIN library.languages l
…till detta:
books b LEFT OUTER JOIN library.languages l
Således ser hela fråge- och resultatuppsättningen nästan identisk ut med INNER JOIN
förutom den mindre ändringen:
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 förväntat, genom att använda en LEFT OUTER JOIN
istället för föregående INNER JOIN
, vi får det bästa av två världar:Vi hoppar inte över några books
poster (som Hamlet
) helt enkelt för att language_id
värdet är null
för den posten, men för alla poster där language_id
existerar får vi det snyggt formaterade language name
hämtat från våra languages
bord.
Utföra yttre sammanfogningar med hjälp av (+)-symbolen
Som anges i den officiella dokumentationen tillhandahåller Oracle en speciell outer join operator
(+
symbol) som är en förkortning för att utföra OUTER JOINS
.
I praktiken är +
symbolen placeras direkt i den villkorliga uttalande och på sidan av den valfria tabellen (den som får innehålla tom eller null
värden inom det villkorliga).
Därför kan vi återigen skriva om vår LEFT OUTER JOIN
ovan uttalande med +
operatör som så:
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;
Resultaten är desamma som standard LEFT OUTER JOIN
exemplet ovan, så vi tar inte med dem här. Det finns dock en viktig aspekt att lägga märke till om syntaxen med +
operator för OUTER JOINS
.
+
operatör måste vara på vänster sida av det villkorliga (vänster om är lika med =
tecken). Därför, i det här fallet, eftersom vi vill säkerställa att våra languages
table är den valfria tabellen som kan returnera null
värden under den här jämförelsen bytte vi tabellernas ordning i detta villkorliga, så languages
är till vänster (och är valfritt) medan books
är till höger.
Slutligen, på grund av denna omordning av tabellsidorna i villkoret när du använder +
operatör är det viktigt att inse att ovanstående bara är en förkortning för en RIGHT OUTER JOIN
. Detta betyder att detta utdrag av frågan:
FROM
books b,
library.languages l
WHERE
l.id (+)= b.language_id
…är faktiskt identisk med detta:
FROM
library.languages l
RIGHT OUTER JOIN
books b
ON
b.language_id = l.id