- Co to jest połączenie wewnętrzne?
- Co to jest złącze zewnętrzne?
- Wykonywanie połączeń zewnętrznych za pomocą symbolu (+)
Podobnie jak praktycznie wszystkie relacyjne bazy danych, Oracle umożliwia generowanie zapytań, które łączą lub JOIN wiersze z dwóch lub więcej tabel, aby utworzyć ostateczny zestaw wyników. Chociaż istnieje wiele rodzajów złączeń, które można wykonać, najczęstsze to INNER JOIN i OUTER JOIN .
W tym samouczku krótko omówimy różnicę między INNER i OUTER JOIN a następnie przyjrzyj się skróconej metodzie Oracle do wykonywania OUTER JOINS konkretnie za pomocą + symbol operatora.
Co to jest połączenie wewnętrzne?
INNER JOIN w relacyjnej bazie danych to po prostu połączenie dwóch lub więcej tabel, w których wynik będzie zawierał tylko te dane, które spełniają wszystkie warunki połączenia .
Na przykład tutaj mamy podstawową library schemat z dwiema tabelami:books i languages . languages tabela to tylko lista możliwych nazw języków i unikalny język 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
Tymczasem nasze books tabela ma language_id wiersz, który w większości książek, ale nie we wszystkich, zawiera po prostu language_id powiązany z oryginalnym językiem publikacji książki:
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
W wielu przypadkach możemy chcieć wykonać INNER JOIN z books i languages tabele więc zamiast przeglądać bezsensowny language_id wartości każdej książki, faktycznie możemy zobaczyć language name zamiast tego.
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
Należy tutaj zauważyć, że nasz zestaw wyników był nieco inny w dwóch powyższych zapytaniach. W pierwszym po prostu wymieniliśmy pierwsze 10 książki, ale w INNER JOIN zapytanie zwracamy tylko wyniki spełniające wszystkie warunki z obu tabel. Z tego powodu zapis Hamlet (który ma language_id wartość null lub puste) jest ignorowane i nie jest zwracane w wyniku naszego INNER JOIN .
Co to jest złącze zewnętrzne?
Zamiast zwracać wyłącznie wyniki, które spełniają wszystkie warunki złączenia INNER JOIN , OUTER JOIN zwraca nie tylko wyniki, które spełniają wszystkie warunki, ale również zwraca wiersze z jednej tabeli, które nie spełniły warunku. Tabela wybrana do tego „pominięcia” wymagań warunkowych jest określona przez kierunek lub „stronę” złączenia, zwykle określaną jako LEFT lub RIGHT połączenia zewnętrzne.
Podczas definiowania strony do OUTER JOIN , określasz, która tabela zawsze zwróci swój wiersz, nawet jeśli przeciwny w tabeli po drugiej stronie złączenia brakuje lub null wartości jako część warunku połączenia.
Dlatego jeśli wykonamy to samo podstawowe JOIN jak powyżej, aby pobrać books i language names , wiemy, że nasze books tabela powinna zawsze zwracać dane, więc nasze JOIN strona powinna „wskazywać” nasze books tabeli, tworząc w ten sposób languages tabela OUTER tabeli, którą do niej dołączamy.
Aby to osiągnąć, po prostu zmieniamy:
books b INNER JOIN library.languages l
…do tego:
books b LEFT OUTER JOIN library.languages l
W ten sposób całe zapytanie i zestaw wyników wygląda prawie identycznie jak INNER JOIN poza tą drobną zmianą:
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
Zgodnie z oczekiwaniami, używając LEFT OUTER JOIN zamiast poprzedniego INNER JOIN , czerpiemy to, co najlepsze z obu światów:nie pomijamy żadnych books rekordy (takie jak Hamlet ) po prostu dlatego, że language_id wartość to null dla tego rekordu, ale dla wszystkich rekordów, w których language_id istnieje, otrzymujemy ładnie sformatowaną language name uzyskane z naszych languages tabela.
Wykonywanie połączeń zewnętrznych przy użyciu symbolu (+)
Jak wskazano w oficjalnej dokumentacji, Oracle zapewnia specjalny outer join operator (+ symbol), który jest skrótem do wykonywania OUTER JOINS .
W praktyce + symbol jest umieszczony bezpośrednio w warunku oświadczenie i po stronie opcjonalnej tabeli (tej, która może zawierać pustą lub null wartości w ramach warunkowego).
Dlatego możemy ponownie przepisać powyższe LEFT OUTER JOIN oświadczenie za pomocą + taki operator:
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;
Wyniki są takie same jak w przypadku standardowego LEFT OUTER JOIN przykład powyżej, więc nie będziemy ich tutaj uwzględniać. Jest jednak jeden krytyczny aspekt, który należy zwrócić uwagę na składnię przy użyciu + operator dla OUTER JOINS .
+ operator musi być po lewej stronie warunku (po lewej stronie równa się = znak). Dlatego w tym przypadku, ponieważ chcemy mieć pewność, że nasze languages table to opcjonalna tabela, która może zwrócić null wartości podczas tego porównania zamieniliśmy kolejność tabel w tym warunku, więc languages znajduje się po lewej stronie (i jest opcjonalne), podczas gdy books jest po prawej stronie.
Wreszcie, z powodu tej zmiany kolejności boków tabeli w trybie warunkowym przy użyciu + operatora, ważne jest, aby zdać sobie sprawę, że powyższe jest po prostu skrótem dla RIGHT OUTER JOIN . Oznacza to, że ten fragment zapytania:
FROM
books b,
library.languages l
WHERE
l.id (+)= b.language_id
…jest w rzeczywistości identyczny z tym:
FROM
library.languages l
RIGHT OUTER JOIN
books b
ON
b.language_id = l.id