- Какво е вътрешно свързване?
- Какво е външно присъединяване?
- Извършване на външни съединения с помощта на символа (+)
Подобно на почти всички релационни бази данни, 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