- Co je vnitřní spojení?
- Co je to vnější spojení?
- Provádění vnějších spojení pomocí symbolu (+)
Jako prakticky všechny relační databáze umožňuje Oracle generovat dotazy, které se kombinují nebo JOIN
řádků ze dvou nebo více tabulek k vytvoření konečné výsledné sady. I když existuje mnoho typů ze spojení, která lze provést, jsou nejběžnější INNER JOIN
a OUTER JOIN
.
V tomto tutoriálu stručně prozkoumáme rozdíl mezi INNER
a OUTER JOIN
a poté prozkoumejte zkrácenou metodu, kterou Oracle poskytuje pro provádění OUTER JOINS
konkrétně pomocí +
symbol operátora.
Co je vnitřní spojení?
INNER JOIN
v relační databázi je jednoduše spojení dvou nebo více tabulek, ve kterých výsledek bude obsahovat pouze data, která splňují všechny podmínky spojení .
Například zde máme základní library
schéma se dvěma tabulkami:books
a languages
. languages
tabulka je pouze seznam možných názvů jazyků a jedinečný jazyk 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
Mezitím naše books
tabulka má language_id
řádek, který u většiny, ale ne u všech knih jednoduše obsahuje language_id
spojené s původním publikovaným jazykem knihy:
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
V mnoha případech můžeme chtít provést INNER JOIN
z books
a languages
tabulky, takže namísto prohlížení nesmyslného language_id
hodnotu každé knihy, můžeme ve skutečnosti vidět language name
místo toho.
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
Zde je důležité poznamenat, že naše sada výsledků se ve dvou výše uvedených dotazech mírně lišila. V prvním jsme jednoduše uvedli prvních 10
knih, ale v INNER JOIN
dotazu, vracíme pouze výsledky, které splňují všechny podmínky z obou tabulek. Z tohoto důvodu záznam Hamlet
(který má language_id
hodnotu null
nebo prázdné) je ignorováno a není vráceno ve výsledku našeho INNER JOIN
.
Co je to vnější spojení?
Místo výlučného vracení výsledků, které splňují všechny podmínky spojení INNER JOIN
, OUTER JOIN
vrací nejen výsledky, které splňují všechny podmínky, ale také vrátí řádky z jedné tabulky, které nesplňují podmínku. Tabulka, která je vybrána pro toto „obejití“ podmíněných požadavků, je určena směrovostí nebo „stranou“ spojení, obvykle označované jako LEFT
nebo RIGHT
vnější spojení.
Při definování strany vašeho OUTER JOIN
, určujete, která tabulka vždy vrátí svůj řádek, i když protichůdné tabulka na druhé straně spojení chybí nebo null
hodnoty jako součást podmínky spojení.
Pokud tedy provedeme stejné základní JOIN
jako výše k načtení books
a language names
, víme, že naše books
tabulka by měla vždy vracet data, takže naše JOIN
strana by měla „ukazovat na“ naše books
tabulku, čímž vytvoříte languages
tabulka OUTER
tabulku, kterou k ní připojujeme.
Abychom toho dosáhli, jednoduše změníme:
books b INNER JOIN library.languages l
…na toto:
books b LEFT OUTER JOIN library.languages l
Celá sada dotazů a výsledků tedy vypadá téměř identicky jako INNER JOIN
kromě té drobné změny:
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
Podle očekávání pomocí LEFT OUTER JOIN
namísto předchozího INNER JOIN
, využíváme to nejlepší z obou světů:Nevynecháváme žádné books
záznamy (například Hamlet
) jednoduše proto, že language_id
hodnota je null
pro tento záznam, ale pro všechny záznamy, kde je language_id
existuje, dostaneme pěkně naformátovaný language name
získané z našich languages
tabulka.
Provádění vnějších spojení pomocí symbolu (+)
Jak je uvedeno v oficiální dokumentaci, Oracle poskytuje speciální outer join operator
(+
symbol), což je zkratka pro provádění OUTER JOINS
.
V praxi to znamená +
symbol je umístěn přímo v podmínce a na straně volitelné tabulky (ta, která může obsahovat prázdné nebo null
hodnoty v rámci podmínky).
Proto můžeme znovu přepsat naše výše uvedené LEFT OUTER JOIN
pomocí +
operátor takto:
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;
Výsledky jsou stejné jako standardní LEFT OUTER JOIN
příklad výše, takže je zde nebudeme uvádět. U syntaxe pomocí +
je však třeba si povšimnout jednoho kritického aspektu operátor pro OUTER JOINS
.
+
operátor musí být na levé straně podmínky (vlevo od rovná se =
podepsat). Proto v tomto případě, protože chceme zajistit, aby naše languages
table je volitelná tabulka, která může vrátit null
hodnoty během tohoto porovnání jsme zaměnili pořadí tabulek v této podmíněné, takže languages
je vlevo (a je volitelný), zatímco books
je vpravo.
A konečně kvůli tomuto přeuspořádání stran tabulky v podmíněném při použití +
operátor, je důležité si uvědomit, že výše uvedené je prostě zkratka pro RIGHT OUTER JOIN
. To znamená, že tento fragment dotazu:
FROM
books b,
library.languages l
WHERE
l.id (+)= b.language_id
…je v podstatě totožné s tímto:
FROM
library.languages l
RIGHT OUTER JOIN
books b
ON
b.language_id = l.id