- 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