sobota, 6 listopada 2010

Kurs Oracle SQL. Proste złączenia

ZŁĄCZENIA


Dane, które chcemy uzyskać z bazy danych zazwyczaj znajdują się w więcej niż jednej tabeli bazodanowej. W takim przypadku nasze zapytanie musi się odpowiednio odwołać do więcej niż jednej tabeli.
Mechanizm ten nazywa się w SQL złączeniami.

Łączenie kartezjańskie



Zapytanie takie zwróci iloczyn kartezjański wierszy z obu tabel.
Złączenia kartezjańskie stosuje się bardzo rzadko, gdyż produkują bardzo dużą ilość wierszy, które nie zawierają logicznie spójnych informacji.
Jeżeli w zapytaniu chcemy odwołać się do kolumny, która występuje w kilku tabelach, to, aby uniknąć niejednoznaczności, odwołanie to musi zawierać nazwę kolumny poprzedzoną nazwą tabeli. Aby uzyskać takie połączenie wystarczy pobrać dane z więcej niż 1 tabeli np. w poniższy sposób:


SELECT * FROM LOCATIONS, DEPARTMENTS;






Jak widzimy w poniższym przykładzie ilość wierszy powstałych w wyniku złączenia kartezjańskiego jest iloczynem ilości wierszy w tabelach departments oraz locations;





ZŁĄCZENIE WEWNĘTRZNE

Złączenia kartezjańskie stosuje się niezwykle rzadko. Najczęściej, kiedy zadajemy zapytanie do dwu tabel, zależy nam na uzyskaniu tylko takich kombinacji wierszy z obu tabel, które sobie w jakiś sposób odpowiadają, np. chcemy klientów i tylko zamówienia przez nich złożone.
Złączenia, które zwracają właśnie taki zbiór wierszy z obu tabel, które sobie w jakimś stopniu odpowiadają nazywamy złączeniami wewnętrznym (inner join).
Aby zrealizować złączenie wewnętrzne w Oracle SQL należy w klauzuli WHERE dodać tzw. warunek złączenia , czyli warunek, w którym określamy jakie wiersze z obu tabel odpowiadają sobie nawzajem. Jeśli nadamy tabeli alias, nie będziemy mogli odnosić się do niej po nazwie.
W tym przykładzie poniżej wyświetliłem nazwy departamentów w połączeniu z miastami w których się znajdują na podstawie danych z dwóch tabel: departments i locations.



ZŁĄCZENIA ZEWNĘTRZNE


W przypadku złączeń wewnętrznych, jeżeli w jednej z tabel istnieje rekord, który nie ma żadnego odpowiednika w drugiej tabeli, to rekord ten jest pomijany w końcowym wyniku.Czasami taka sytuacja nas nie zadawala. W takim wypadku możemy wyróżnić jedną z tabel i wykonać tzw. złączenie zewnętrzne (outer join), aby otrzymać z wyróżnionej tabeli wszystkie rekordy, nawet te, które nie mają swojego odpowiednika w drugiej z tabel.
Aby wykonać złączenie zewnętrzne musimy skorzystać z operatora złączenia zewnętrznego „(+)”. Umieszczamy go w warunku złączenia po nazwie kolumny z tabeli która jest „uboższa”, czyli tam, gdzie „brakuje” rekordów. Poniżej widzimy iż zostały wyświetlone również te lokalizacje do których nie zostały przypisane żadne departamenty.




SAMOZŁĄCZENIA

Czasami zachodzi potrzeba odwołania się w jednym zapytaniu dwukrotnie do tej samej tabeli. Poniżej wyświetlam nazwisko pracownika, numer id jego managera oraz nazwisko managera. Dzieje się tak ponieważ tabelę employees potraktowałem jako dwie różne tabele. Manager_id odpowiada polu employee_id przełożonego, więc w tym wypadku tabela employee zostałą potraktowana tak jak dwie tabele – zawierająca pracowników oraz zawierająca managerów.

















Ten temat omawiam na poniższych szkoleniach:
• Podstawy Oracle SQL
• Podstawy SQL i PL/SQL
Możesz w nich uczestniczyć, a jako czytelnik tego bloga otrzymasz 10% zniżki - poinformuj o tym fakcie konsultanta.

4 komentarze:

  1. Drogi autorze, angielski termin "manager" już dawno temu zotał spolszczony:
    http://pl.wikipedia.org/wiki/Mened%C5%BCer

    OdpowiedzUsuń
  2. Z jedenj strony racja, ale z drugiej istotniejszą jest potrzeba operowania w opisach operacji nazwami, które są jak najbardziej zbliżone do występujących w omawianych strukturach. Więc menedżer, jeśli nazwiemy tak kolumny w schemacie tabeli.

    OdpowiedzUsuń
  3. Jak to się dzieje, że w tym zapytaniu literki "e" i "m" mają taką cudowną moc?:)
    Nie bardzo rozumiem jaka jest ich rola.
    Dzięki temu odwołujemy się dwukrotnie do tej samej tabeli ale przydałoby się coś więcej na ten temat bo to dość enigmatyczne:/



    SELECT
    e.last_name, e.manager_id, m.last_name
    FROM
    employees e, employees m
    WHERE
    e.manager_id=m.employee_id;

    OdpowiedzUsuń