Bazy danych - Akademia Morska w Gdyni

Transkrypt

Bazy danych - Akademia Morska w Gdyni
Bazy danych
Język SQL – Złączenia
Laboratorium
Akademia Morska w Gdyni
Gdynia 2004
Przedmiot
Typ zajęć
Temat
Bazy danych
Laboratorium
Język SQL – Złączenia
1. Złączenie – definicja
Złączenie (JOIN) to zbiór rekordów stanowiących wynik zapytania służącego
pobraniu danych z połączonych tabel (związki „jeden-do-jeden”, „jeden-do-wiele” lub
„wiele-do-wiele”).
Istnieją dwa podstawowe sposoby konstruowania złączeń (instrukcja SELECT):
1. łączone tabele w klauzuli FROM i warunki złączenia w WHERE
2. zastosowanie instrukcji JOIN w ramach składni instrukcji SELECT
W czasie konstrukcji zapytań ze złączeniem dowolnego typu bardzo pomocne okazują
się rozszerzone diagramy związków encji (E-R), na których ujęta jest zależność klucz
obcy-klucz główny łączonych tabeli (a więc tabeli mogących podlegać złączeniu).
wydawnictwa
id
nazwa
ulica
miasto
telefon
fax
numer konta
ksiazki
id
tytul
cena
isbn
data_wydania
wydawnictwa_id
ksiazki_autorzy
id
ksiazki_id
autorzy_id
autorzy
id
imie
nazwisko
tytul_naukowy
wiek
Legenda:
klucz główny
klucz obcy
Rysunek 1 – Rozszerzony diagram E-R dla bazy danych wykorzystywanej na
zajęciach
1.1. Złączenie z użyciem FROM i WHERE
W przypadku dwóch tabel, połączonych za pomocą klucza obcego wskazującego na
klucz główny drugiej tabeli (związki „jeden-do-jeden” i „jeden-do-wiele”), najczęściej
chcemy zawęzić wynik iloczynu kartezjańskiego tych tabel, który byłyby zwrócony
przez proste zapytanie np.:
SELECT * from ksiazki, wydawnictwa;
Ze zbioru wszystkich par rekordów k i w, takich, że rekord k pochodzi z tabeli ksiazki
a rekord w z tabeli wydawnictwa (związek „jeden-do-wiele”, wiele książek w ramach
jednego wydawnictwa), chcemy wybrać tylko te pary rekordów k i w dla których
prawdziwy jest związek: książka określona rekordem k została wydana przez
Joanna Szłapczyńska ([email protected])
Strona 2 z 7
Przedmiot
Typ zajęć
Temat
Bazy danych
Laboratorium
Język SQL – Złączenia
wydawnictwo w. Taką operację można zrealizować w oparciu o znaną już klauzulę
filtracji wyników WHERE:
SELECT * from ksiazki, wydawnictwa
WHERE ksiazki.wydawnictwa_id=wydawnictwa.id;
Aby zapewnić prawidłowy dostęp do pól (np. kolumna ID występuje zarówno w tabeli
ksiazki jak również w tabeli wydawnictwa) w powyższym przykładzie zastosowano
kwalifikator : <nazwa_tabeli>.<nazwa_kolumny>.
Przykład:
Wybranie wszystkich par: tytuł książki oraz nazwa wydawnictwa, które tą książkę
wydało:
SELECT ksiazki.tytul, wydawnictwa.nazwa from ksiazki, wydawnictwa
WHERE ksiazki.wydawnictwa_id=wydawnictwa.id;
Uwaga:
W przypadku złączeń definiowanych za pomocą klauzul FROM i WHERE (sposób 1.)
RDBMS najpierw tworzy wstępny zbiór wyników będący iloczynem kartezjańskim, a
dopiero później wyszukuje te rekordy, które spełniają zadany warunek w klauzuli
WHERE.
1.2. Złączenie z użyciem klauzuli JOIN
W przypadku stosowania klauzuli JOIN zbiór wstępnych wyników jest najczęściej
znacznie mniejszy, ograniczany jest warunkiem po słowie kluczowym ON.
Złączenia konstruowane zgodnie ze sposobem 2. wymagają użycia instrukcji JOIN w
miejscu nazw tabel po słowie kluczowym FROM instrukcji SELECT.
Składnia instrukcji JOIN (http://www.mysql.com/doc/en/JOIN.html):
table_reference, table_reference
table_reference [INNER | CROSS] JOIN table_reference [join_condition]
table_reference STRAIGHT_JOIN table_reference
table_reference LEFT [OUTER] JOIN table_reference [join_condition]
table_reference NATURAL [LEFT [OUTER]] JOIN table_reference
{ OJ table_reference LEFT OUTER JOIN table_reference
ON conditional_expr }
table_reference RIGHT [OUTER] JOIN table_reference [join_condition]
table_reference NATURAL [RIGHT [OUTER]] JOIN table_reference
Joanna Szłapczyńska ([email protected])
Strona 3 z 7
Przedmiot
Typ zajęć
Temat
Bazy danych
Laboratorium
Język SQL – Złączenia
gdzie table_reference jest zdefiniowane jako:
table_name [[AS] alias]
[[USE INDEX (key_list)]
| [IGNORE INDEX (key_list)]
| [FORCE INDEX (key_list)]]
a join_condition jest zdefiniowany jako:
ON conditional_expr | USING (column_list)
Kolejne rozdziały opracowania omawiają główne typy złączeń realizowanych w oparciu
o instrukcję JOIN wraz z przykładami.
2. Złączenia wewnętrzne (INNER JOIN)
Złączenie wewnętrzne (INNER JOIN) to zbiór rekordów będący iloczynem
kartezjańskim łączonych tabel ograniczony przez dodatkowe warunki złączenia,
najczęściej są to warunki równości kluczy głównego i obcego (tzw. złączenie
równościowe - EQUIJOIN).
Równoważne składnie złączeń wewnętrznych:
1. SELECT <kolumna_1>,...<kolumna_n> from <nazwa_tabeli_1>,
<nazwa_tabeli_2> WHERE <warunek_połączenia>
2. SELECT <kolumna_1>,...<kolumna_n> from <nazwa_tabeli_1> INNER
JOIN <nazwa_tabeli_2> {ON <warunek_połączenia>| USING <lista
kolumn>}
3. SELECT <kolumna_1>,...<kolumna_n> from <nazwa_tabeli_1> CROSS JOIN
<nazwa_tabeli_2> {ON <warunek_połączenia>| USING <lista kolumn>}
4. SELECT <kolumna_1>,...<kolumna_n> from <nazwa_tabeli_1> JOIN
<nazwa_tabeli_2> {ON <warunek_połączenia>| USING <lista kolumn>}
Ponieważ domyślnym typem złączenia (JOIN) jest w MySQL złączenie wewnętrzne
składnie JOIN oraz INNER JOIN są równoważne. Polecenie CROSS JOIN, służące do
realizacji iloczynu kartezjańskiego, jest również tożsame ze złączeniem wewnętrznym
INNER JOIN w sytuacji, gdy CROSS JOIN posiada określony warunek złączenia.
Przykład:
Wybranie wszystkich par: tytuł książki oraz nazwa wydawnictwa, które tą książkę
wydało (równoważne składniowo sposoby):
Joanna Szłapczyńska ([email protected])
Strona 4 z 7
Przedmiot
Typ zajęć
Temat
Bazy danych
Laboratorium
Język SQL – Złączenia
SELECT ksiazki.tytul, wydawnictwa.nazwa from ksiazki, wydawnictwa
WHERE ksiazki.wydawnictwa_id=wydawnictwa.id;
SELECT ksiazki.tytul, wydawnictwa.nazwa from ksiazki INNER JOIN
wydawnictwa ON ksiazki.wydawnictwa_id=wydawnictwa.id;
SELECT ksiazki.tytul, wydawnictwa.nazwa from ksiazki CROSS JOIN
wydawnictwa ON ksiazki.wydawnictwa_id=wydawnictwa.id;
SELECT ksiazki.tytul, wydawnictwa.nazwa from ksiazki JOIN wydawnictwa
ON ksiazki.wydawnictwa_id=wydawnictwa.id;
Uwaga:
W przypadku, jeśli jedna z porównywanych kolumn (w równościowym warunku
złączenia) przyjmuje wartość NULL jej wartość nie znajdzie się w wyniku tego
złączenia (zgodnie z ogólnymi zasadami obsługiwania wartości NULL przez operacje
porównania). Jest to ważna cecha charakterystyczna złączeń wewnętrznych.
W powyższym przykładzie złączenie wewnętrzne nie zawiera ani tych wydawnictw,
które nie wydały żadnej książki ani też tych książek, dla których jeszcze nie
znaleziono wydawcy.
Składnia języka SQL umożliwia nadawanie aliasów nazwom tabel, co znacznie ułatwia
odwoływanie się do kolumn poprzez kwalifikator
<alias>.<nazwa_kolumny>
zamiast:
<nazwa_tabeli>.<nazwa_kolumny>
Przykład:
Wybranie wszystkich par: tytuł książki oraz nazwa wydawnictwa, które tą książkę
wydało przy wykorzystaniu aliasowania nazw tabel:
SELECT k.tytul, w.nazwa from ksiazki AS k INNER JOIN wydawnictwa AS w
ON k.wydawnictwa_id=w.id;
Jeśli łączone tabele posiadają te same nazwy kolumn łączących (kluczy obcych i
kluczy głównych) możemy zastosować jedną z równoważnych klauzul: USING lub też
NATURAL JOIN zgodnie ze składnią:
... A INNER JOIN B USING (<nazwa_kolumny_1>, ..., <nazwa_kolumny_1>)...
.. A NATURAL JOIN B …
Joanna Szłapczyńska ([email protected])
Strona 5 z 7
Przedmiot
Typ zajęć
Temat
Bazy danych
Laboratorium
Język SQL – Złączenia
Wywołanie z użyciem klauzuli USING wymaga, aby obie łączone tabele posiadały
wszystkie pola wymienione na liście.
Natomiast złączenie NATURAL JOIN oznacza złączenie wewnętrzne dla warunku
równości wszystkich kolumn o tych samych nazwach w łączonych tablicach (uwaga:
nie jest wymagane specyfikowanie nazw kolumn i RDBMS automatycznie wyszukuje
kolumny o tych samych nazwach!).
Przykład:
Wybranie wszystkich par: tytuł książki oraz nazwa wydawnictwa, które tą książkę
wydało, przy założeniu, że tablica ksiązki ma zdefiniowany klucz główny jako
„ksiazki_id” oraz klucz obcy jako „wydawnictwa_id” oraz tablica wydawnictwa ma
zdefiniowany klucz główny jako „wydawnictwa_id” (równoważne sposoby):
SELECT ksiazki.tytul, wydawnictwa.nazwa from ksiazki INNER JOIN
wydawnictwa USING (wydawnictwa_id);
SELECT ksiazki.tytul, wydawnictwa.nazwa from ksiazki NATURAL JOIN
wydawnictwa;
3. Złączenia zewnętrzne (OUTER JOIN)
Złączenia zewnętrzne (OUTER JOIN) rozszerzają pojęcie złączenia wewnętrznego
zwracając rekordy, które spełniają określone warunki złączenia oraz wszystkie inne
rekordy z jednej (lub obu) łączonych tabel. Wyróżniamy następujące typy złączeń
zewnętrznych:
•
Złączenie
lewe
(LEFT
JOIN)
–
rozszerza
zbiór
rekordów
złączenia
wewnętrznego o te rekordy z tablicy z lewej strony złączenia, dla których nie
przyporządkowano żadnych odpowiadających rekordów z tablicy prawej w
złączeniu
•
Złączenie prawe (RIGHT JOIN) – analogicznie do złączenia lewego, tylko
odpowiednio dla prawej strony złączenia
•
Złączenie zewnętrzne pełne (FULL JOIN) - rozszerza zbiór rekordów złączenia
wewnętrznego o te rekordy z tablicy z lewej oraz prawej złączenia, dla nie
przyporządkowano żadnych odpowiadających rekordów z łączonej tablicy
Składnia złączeń zewnętrznych w MySQL:
•
Złączenie lewe (LEFT JOIN)
Joanna Szłapczyńska ([email protected])
Strona 6 z 7
Przedmiot
Typ zajęć
Temat
Bazy danych
Laboratorium
Język SQL – Złączenia
SELECT <kolumna_1>,...<kolumna_n> from <nazwa_tabeli_1> LEFT JOIN
<nazwa_tabeli_2> {ON <warunek_połączenia>| USING <lista kolumn>}
•
Złączenie prawe (RIGHT JOIN)
SELECT <kolumna_1>,...<kolumna_n> from <nazwa_tabeli_1> RIGHT JOIN
<nazwa_tabeli_2> {ON <warunek_połączenia>| USING <lista kolumn>}
•
Złączenie pełne (FULL JOIN)
W obecnej wersji MySQL (4.1.1) złączenie pełne nie jest obsługiwane.
Przykład:
Wyświetlenie pełnej listy nazw wydawnictw wraz z wydanymi przez nie książkami (z
uwzględnieniem tych wydawnictw, które do tej pory nie wydały żadnej książki)
(równoważne sposoby):
SELECT ksiazki.tytul, wydawnictwa.nazwa from wydawnictwa
LEFT JOIN ksiazki on ksiazki.wydawnictwa_id=wydawnictwa.id;
SELECT ksiazki.tytul, wydawnictwa.nazwa from ksiazki
RIGHT JOIN wydawnictwa on ksiazki.wydawnictwa_id=wydawnictwa.id;
Dopuszczalne jest również tworzenie złączenia (wewnętrznego lub zewnętrznego)
kilkukrotnie, tak aby zrealizować połączenie więcej niż dwóch tabel. Np. dla złączenia
tabel A, B i C stosujemy notację:
FROM A JOIN B ON <warunek_zlaczenia_1>
JOIN C ON <warunek_zlaczenia_2>
Przykład:
Wyświetlenie pełnej listy autorów wraz z tytułami książek które napisali (z
uwzględnieniem tych autorów, którzy na razie nie wydali żadnej książki):
SELECT imie, nazwisko, tytul
FROM autorzy LEFT JOIN ksiazki_autorzy ON
ksiazki_autorzy.autorzy_id=autorzy.id
LEFT JOIN ksiazki
ON ksiazki_autorzy.ksiazki_id=ksiazki.id
ORDER BY nazwisko;
Joanna Szłapczyńska ([email protected])
Strona 7 z 7