- Какво е вътрешно свързване?
- Какво е външно присъединяване?
- Извършване на външни съединения с помощта на символа (+)
Подобно на почти всички релационни бази данни, Oracle позволява генерирането на заявки, които комбинират или JOIN редове от две или повече таблици, за да създадете крайния набор от резултати. Въпреки че има много видове от съединенията, които могат да бъдат извършени, най-често срещаните са INNER JOIN и OUTER JOIN .
В този урок ще разгледаме накратко разликата между INNER и OUTER JOIN и след това разгледайте стенографския метод, който Oracle предоставя за извършване на OUTER JOINS специално с помощта на + символ на оператор.
Какво е вътрешно присъединяване?
INNER JOIN в релационна база данни е просто обединяване на две или повече таблици, в които резултатът ще съдържа само данни, които отговарят на всички условия за присъединяване .
Например, тук имаме основна library схема с две таблици:books и languages . languages таблицата е просто списък с възможни имена на езици и уникален език 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
Междувременно нашите books таблицата има language_id ред, който за повечето, но не всички книги просто съдържа language_id свързани с оригиналния публикуван език на книгата:
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
В много случаи може да пожелаем да извършим INNER JOIN от books и languages таблици така, вместо да преглеждате безсмисления language_id стойността на всяка книга, всъщност можем да видим language name вместо това.
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
Това, което е важно да се отбележи тук, е, че нашият набор от резултати беше малко по-различен в горните две заявки. В първия просто изброихме първите 10 книги, но в INNER JOIN заявка, ние връщаме само резултати, които отговарят на всички условия от двете таблици. Поради тази причина записът на Hamlet (който има language_id стойност на null или празен) се игнорира и не се връща в резултата от нашето INNER JOIN .
Какво е външно присъединяване?
Вместо да връща изключително резултати, които отговарят на всички условия за присъединяване на INNER JOIN , OUTER JOIN връща не само резултати, които отговарят на всички условия, но исъщо връща редове от една таблица, които не отговарят на условието. Таблицата, която е избрана за това „заобикаляне“ на условните изисквания, се определя от насочеността или „страна“ на съединението, обикновено наричано LEFT или RIGHT външни съединения.
Когато дефинирате страна на вашето OUTER JOIN , указвате коя таблица винаги ще връща своя ред, дори ако противоположният таблицата от другата страна на съединението липсва или null стойности като част от условието за присъединяване.
Следователно, ако изпълним същия основен JOIN както по-горе, за да извлечете books и language names , знаем, че нашите books таблицата винаги трябва да връща данни, така че нашият JOIN страната трябва да "сочи към" нашите books таблица, като по този начин правим languages таблица OUTER таблица, която прикачваме към нея.
За да постигнем това, ние просто променяме:
books b INNER JOIN library.languages l
...на това:
books b LEFT OUTER JOIN library.languages l
По този начин цялата заявка и набор от резултати изглеждат почти идентични с INNER JOIN с изключение на малката промяна:
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
Както се очакваше, с помощта на LEFT OUTER JOIN вместо предишното INNER JOIN , получаваме най-доброто от двата свята:не пропускаме никакви books записи (като Hamlet ) просто защото language_id стойността е null за този запис, но за всички записи, където language_id съществува, получаваме добре форматираното language name получени от нашите languages таблица.
Извършване на външни присъединявания с помощта на символа (+)
Както е посочено в официалната документация, Oracle предоставя специален outer join operator (+ символ), което е съкратено за извършване на OUTER JOINS .
На практика + символът се поставя директно в условното оператор и от страната на незадължителната таблица (тази, на която е позволено да съдържа празно или null стойности в рамките на условното).
Следователно можем отново да пренапишем нашето по-горе LEFT OUTER JOIN израз с помощта на + оператор така:
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;
Резултатите са същите като стандартното LEFT OUTER JOIN пример по-горе, така че няма да ги включваме тук. Има обаче един критичен аспект, който трябва да забележите относно синтаксиса с помощта на + оператор за OUTER JOINS .
+ оператор трябва да бъде от лявата страна на условното (отляво от равно = знак). Следователно, в този случай, защото искаме да гарантираме, че нашите languages table е незадължителната таблица, която може да върне null стойности по време на това сравнение сменихме реда на таблиците в това условие, така че languages е отляво (и е по избор), докато books е вдясно.
И накрая, поради това пренареждане на страните на таблицата в условното при използване на + оператор, важно е да разберете, че горното е просто стенография за RIGHT OUTER JOIN . Това означава, че този фрагмент от заявката:
FROM
books b,
library.languages l
WHERE
l.id (+)= b.language_id
…е на практика идентично с това:
FROM
library.languages l
RIGHT OUTER JOIN
books b
ON
b.language_id = l.id