Język SQL – zapytania zagnieżdżone (podzapytania)
Zapytania zagnieżdżone Język SQL pozwala na zagnieżdżanie zapytań (podzapytania) Oznacza to, że wynik jednego zapytania może być wykorzystany przez inne zapytanie, będące jego nadzapytaniem Inaczej – jedno zapytanie może w klauzuli where zawierać inne, zagnieżdżone zapytanie.
Zapytania zagnieżdżone – przykład 1 Podaj towary z działu, którego kierownikiem jest Kowalski select nazwa from towary where dzial = (select dzial from dzialy where kierownik = ‘Kowalski’) podzapytanie zwraca numer działu, którego kierownikiem jest Kowalski; wartość ta jest następnie wykorzystana w nadzapytaniu w warunku where
Zapytania zagnieżdżone c.d. Standardowym zastosowaniem zapytań zagnieżdżonych jest testowanie przynależności do zbioru, porównywanie zbiorów, oraz sprawdzanie liczebności zbioru. Operatory należenia do zbioru: IN (należy) NOT IN (nie należy)
Zapytania zagnieżdżone – przykład 2 Podaj towary z działów, których kierownikiem jest Kowalski select nazwa from towary where dzial in (select dzial from dzialy where kierownik = ‘Kowalski’) Jeżeli Kowalski jest kierownikiem więcej niż jednego działu, podzapytanie zwróci zbiór wartości. Dlatego zamiast znaku = musimy zastosować operator in
Zapytania zagnieżdżone – przykład 3 select nazwisko, imie from pracownicy where pesel in (select peselp from obsada where rok_akad = '2003L') Pracownicy, którzy mają zajęcia na wydziale w semestrze letnim w roku akademickim 2003
Zadania Podaj nazwiska pracowników, którzy pracują w dziale ‘SYSTEMY EKSPERCKIE’ Podaj nazwiska pracowników, którzy pracują na Piotrowie. Podaj nazwę działu, w którym nie pracuje żaden pracownik.
Zadania Podaj nazwiska pracowników, którzy pracują na tym samym stanowisku co Hapke. Podaj nazwisko najlepiej zarabiającego pracownika. Podaj nazwiska pracowników zarabiających powyżej średniej.
Klauzula SOME 5 6 5 5 5 (= some) in Jednakże, ( some) not in F <porównanie> some r t r : (F <porównanie> t) gdzie <porównanie> to: 5 6 (5< some ) = true (read: 5 < some tuple in the relation) (5< some ) = false 5 (5 = some ) = true 5 (5 some ) = true (bo 0 5) 5 (= some) in Jednakże, ( some) not in
Klauzula ALL F <porówn> all r t r (F <porówn> t) 5 5 6 (5< all ) = false 6 (5< all ) = true 10 4 (5 = all ) = false 5 4 (5 all ) = true (bo 5 4 i 5 6) 6 ( all) not in Jednakże, (= all) in
Klauzula ALL - przykład select nazwa from towary where cena >= ALL (select cena where rodzaj = ‘AGD’) Wybierz towary, których cena jest wyższa od każdej z cen towarów AGD (można oczywiście w tym przypadku zastąpić MAX)
Zadania Podaj nazwiska i stanowiska pracowników, którzy pracują na stanowiskach nie obsadzonych w dziale 20 (wykorzystaj ALL). Sprawdź, czy istnieją pracownicy zatrudnieni wcześniej od wszystkich pracowników Systemów Rozproszonych (wykorzystaj ALL). Sprawdź, czy BRZEZINSKI zarabia więcej od któregokolwiek z innych profesorów (wykorzystaj SOME; jeżeli tak – wypisz ‘TAK’).
Podzapytania skorelowane Dotychczasowe przykłady dotyczyły podzapytań nieskorelowanych – były one obliczane tylko raz, były niezależne od nadzapytania Podzapytania skorelowane – zależą od tego, jakie wartości są przetwarzane w nadzapytaniu, wykonywane są wielokrotnie dla zmieniających się wartości
Przykład Podaj nazwę najdroższego towaru od każdego z dostawców. select nazwa from towary T1 where cena = (select max(cena) from towary T2 where T2.dostawca = T1.dostawca) Podzapytanie zwraca najwyższą cenę u danego dostawcy. Wynik podzapytania zależy od tego kto jest dostawcą towaru aktualnie analizowanego w nadzapytaniu
Zadania Dla każdego działu podaj nazwisko najmniej zarabiającego pracownika. Podaj nazwiska pracowników, którzy zarabiają więcej od swojego szefa. Podaj nazwiska pracowników, których płaca nie mieści się w ‘widełkach’ płacowych na ich stanowisku. Podaj nazwę działu, w którym pracuje najlepiej zarabiający pracownik.
Test istnienia Konstrukcja exists zwraca wartość true jeżeli argument zwracany jako wartość podzapytania jest niepusty. exists r r Ø not exists r r = Ø
Test istnienia - przykład Podaj działy, w których nie ma towarów. select * from dzialy d where not exists (select * from towary t where t.dzial = d.dzial)
Zadania – wykorzystaj exists/not exists Podaj działy, w których nie pracuje żaden pracownik. Podaj nazwiska pracowników, którzy mają chociaż jednego podwładnego. Podaj działy, w których chociaż jeden profesor zarabia powyżej 1000.
Zadanka ekstra Podaj nazwiska trzech najlepiej zarabiających pracowników (z możliwością uogólnienia na n pracowników) Znajdź dział zatrudniający najwięcej pracowników. Sprawdź, czy istnieje pracownik, który ma podwładnych w każdym z działów (oprócz 50 oczywiście). w razie braku pomysłów – wskazówki na następnym slajdzie...
Zadanka ekstra - wskazówki być jednym z trzech najlepiej zarabiających to znaczy, że co najwyżej dwie osoby zarabiają lepiej; Wykorzystaj podzapytanie zliczające te osoby; wynik podzapytania można przyrównać do liczby nie można zrobić max(count(_)); wykorzystaj ALL „pracownik, który ma podwładnych w każdym z działów” to inaczej: „nie istnieje dział, który nie zatrudnia podwładnych danego pracownika”; wykorzystaj „not exists”