• Nie Znaleziono Wyników

(c) Instytut Informatyki Politechniki Poznańskiej 1Język SQL. Rozdział 6b.Podzapytania –konstrukcje zaawansowanePodzapytania skorelowane. Operator EXISTS.Podzapytania w klauzulach SELECT,FROM i ORDER BY.

N/A
N/A
Protected

Academic year: 2021

Share "(c) Instytut Informatyki Politechniki Poznańskiej 1Język SQL. Rozdział 6b.Podzapytania –konstrukcje zaawansowanePodzapytania skorelowane. Operator EXISTS.Podzapytania w klauzulach SELECT,FROM i ORDER BY."

Copied!
13
0
0

Pełen tekst

(1)

Język SQL. Rozdział 6b.

Podzapytania – konstrukcje zaawansowane

Podzapytania skorelowane. Operator EXISTS.

Podzapytania w klauzulach SELECT, FROM i ORDER BY.

(2)

Czy podzapytania "zwykłe" są wystarczające?

• Przykład 1. Podaj dane najgorzej opłacanych pracowników w poszczególnych zespołach.

Zbiory danych:

SELECT id_zesp, nazwisko, placa_pod FROM pracownicy WHERE (id_zesp, placa_pod) IN

(SELECT id_zesp, MIN(placa_pod)

FROM pracownicy GROUP BY id_zesp) ORDER BY id_zesp, nazwisko;

ID_ZESP MIN(PLACA_POD)

10 410.2

20 371

30 208

40 1350

ID_ZESP NAZWISKO PLACA_POD

10 MAREK 410.2

10 WEGLARZ 1730

20 BRZEZINSKI 960

20 JEZIERSKI 439.7

20 KONOPKA 480

20 KOSZLAJDA 590

podzapytanie

zapytanie główne

(3)

Czy podzapytania "zwykłe" są wystarczające?

Zbiory danych:

Wykonanie:

1. MAREK: (10,410.2) IN ((10,410.2),(20,371),(30,208),(40,1350)) 2. WEGLARZ: (10, 1730) IN ((10,410.2),(20,371),(30,208),(40,1350)) 3.

Ogólnie:

<pracownik>: (id_zesp, placa_pod) IN (id_zesp, MIN(placa_pod))

Inaczej: zapytanie_główne.id_zesp = podzapytanie.id_zesp AND

zapytanie_główne.placa_pod = podzapytanie.MIN(placa_pod)

ID_ZESP MIN(PLACA_POD)

10 410.2

20 371

30 208

40 1350

ID_ZESP NAZWISKO PLACA_POD

10 MAREK 410.2

10 WEGLARZ 1730

20 BRZEZINSKI 960

20 JEZIERSKI 439.7

20 KONOPKA 480

20 KOSZLAJDA 590

podzapytanie

zapytanie główne

(4)

Czy podzapytania "zwykłe" są wystarczające?

• Przykład 2. Podaj dane pracowników zarabiających więcej od najgorzej opłacanych pracowników w poszczególnych zespołach.

• Warunki:

• Problem:

• zapytania składowe korzystają z różnych operatorów.

• Zapytanie:

zapytanie_główne.id_zesp = podzapytanie.id_zesp AND

zapytanie_główne.placa_pod > podzapytanie.MIN(placa_pod)

SELECT id_zesp, nazwisko, placa_pod FROM pracownicy WHERE (id_zesp, placa_pod) ???

(SELECT id_zesp, MIN(placa_pod)

FROM pracownicy GROUP BY id_zesp) ORDER BY id_zesp, nazwisko;

(5)

Podzapytanie skorelowane (1)

• Pozwala na wykonanie selekcji niedostępnych dla podzapytań zwykłych (bez korelacji).

• Wykonywane wielokrotnie – dla każdego rekordu przeglądanego przez zapytanie główne.

• Operuje na wartościach atrybutów przekazanych przez zapytanie główne.

• Zawsze odwołuje się do atrybutu zapytania głównego (w klauzuli WHERE lub HAVING).

SELECT atrybuta, atrybutb, ...

FROM relacja

WHERE atrybutn >=

(SELECT atrybutj FROM relacja

WHERE atrybutj = atrybutb);

zapytanie główne

podzapytanie skorelowane

(6)

Podzapytanie skorelowane (2)

• Wykonanie:

1. Pobranie rekordu Ri przez zapytanie główne.

2. Wykonanie podzapytania na podstawie wartości z rekordu Ri 3. Zaakceptowanie bądź odrzucenie rekordu Ri.

4. Pobranie kolejnego rekordu Ri+1 przez zapytanie główne i powtórzenie kroków od 2. do 4.

• Przykład:

Wyświetl dane pracowników zarabiających więcej niż najgorzej opłacany pracownik zespołu, w którym pracują.

SELECT nazwisko, placa_pod, id_zesp FROM pracownicy p

WHERE placa_pod >

(SELECT MIN(placa_pod) FROM pracownicy

WHERE id_zesp = p.id_zesp);

(7)

Podzapytanie skorelowane (3)

NAZWISKO PLACA_POD

LECH 300

CZECH 400

RUS PIAST

400 500

ID_ZESP

1 1 2 2

Pracownicy

NAZWISKO PLACA_POD

LECH 300

CZECH 400

RUS PIAST

400 500

ID_ZESP

1 1 2 2

P

SELECT nazwisko, placa_pod, id_zesp FROM pracownicy p

WHERE placa_pod >

(SELECT MIN(placa_pod) FROM pracownicy

WHERE id_zesp = p.id_zesp);

(8)

• Zwraca wartość prawdy jeżeli podzapytanie zwraca jakikolwiek rekord. Podzapytanie nie musi zwracać wartości z bazy danych, równie dobrze może zwracać dowolny literał.

• Przykłady:

Operator EXISTS

SELECT id_prac, nazwisko, etat, id_zesp FROM pracownicy p

WHERE EXISTS (SELECT * FROM pracownicy WHERE id_szefa = p.id_prac);

SELECT nazwisko, etat, id_zesp FROM pracownicy p

WHERE NOT EXISTS (SELECT 'A' FROM zespoly WHERE id_zesp = p.id_zesp);

(9)

• Jest źródłem danych dla jednej kolumny zbioru wynikowego.

• Musi zwrócić co najwyżej jedną wartość dla każdego rekordu zapytania głównego (często osiągane przez korelację).

• Przykłady:

SELECT nazwa, (SELECT MAX(placa_pod) FROM pracownicy

WHERE id_zesp = z.id_zesp) AS maks_placa FROM zespoly z

ORDER BY nazwa;

SELECT nazwisko, (SELECT nazwisko FROM pracownicy

WHERE id_prac = p.id_szefa) AS szef FROM pracownicy p

ORDER BY nazwisko;

Podzapytanie w klauzuli SELECT (1)

(10)

• Przykłady:

• Uwaga! Często problem można rozwiązać bez ww. konstrukcji.

SELECT nazwa, (SELECT MAX(placa_pod) FROM pracownicy

WHERE etat = nazwa) AS maks_placa, (SELECT AVG(placa_pod)

FROM pracownicy

WHERE etat = nazwa) AS średnia_placa FROM etaty

ORDER BY nazwa;

Podzapytanie w klauzuli SELECT (2)

SELECT nazwa, MAX(placa_pod) AS maks_placa, AVG(placa_pod) AS średnia_placa

FROM etaty LEFT JOIN pracownicy ON etat = nazwa GROUP BY nazwa

ORDER BY nazwa;

(11)

Podzapytanie w klauzuli FROM (1)

• Tworzy wejściowy zbiór danych dla zapytania głównego – pozwala to na rozbicie rozwiązania problemu na etapy.

• Dopuszczalne użycie klauzuli ORDER BY.

• Podzapytanie może mieć zdefiniowany alias.

• Przykład:

• Znajdź pracowników zarabiających rocznie ponad 15 000 zł.

SELECT nazwisko, suma FROM (SELECT nazwisko,

12*placa_pod + COALESCE(placa_dod, 0) AS suma FROM pracownicy)

WHERE suma > 15000 ORDER BY suma DESC;

(12)

Podzapytanie w klauzuli FROM (2)

• Przykład:

• Wyświetl nazwiska pracowników, którzy zarabiają więcej niż średnia płaca w zespole, w którym pracują.

SELECT nazwisko, placa_pod, srednia_w_zespole

FROM (SELECT id_zesp, AVG(placa_pod) AS srednia_w_zespole FROM pracownicy

GROUP BY id_zesp) z

JOIN pracownicy p ON z.id_zesp = p.id_zesp WHERE placa_pod > srednia_w_zespole

ORDER BY srednia_w_zespole DESC;

(13)

Podzapytanie w klauzuli ORDER BY

• Wynik podzapytania jest wykorzystywany do uporządkowania zbioru wynikowego zapytania głównego.

• Podzapytanie dla każdego rekordu zapytania głównego musi zwrócić dokładnie jedną wartość.

• Przykład:

• Pokaż nazwiska wszystkich pracowników. Wynik uporządkuj w kolejności malejącej wg liczności zespołów, do których należą pracownicy, oraz rosnąco wg nazwisk pracowników.

SELECT nazwisko FROM pracownicy p

ORDER BY (SELECT COUNT(*) FROM pracownicy

WHERE p.id_zesp = id_zesp) DESC, nazwisko;

Cytaty

Powiązane dokumenty

Podzapytanie proste to takie podzapytanie, które jest wykonywane tylko raz, a jego wynik jest następnie wykorzystywany w zapytaniu głównym... 0gólna postać

e) Podaj osoby, których nazwiska zaczynają się na No. f) Podaj osoby, których imiona nie zaczynają się na literę A. Użyj operatora IN. Wyniki posortuj malejąco według

Wynikiem zapytania typu SELECT jest tablica zawierająca określone kolumny i dane.. Skoro jest to tablica, to

(SELECT nazwa, SUM(placa_pod) AS suma_plac FROM pracownicy JOIN zespoly USING (id_zesp) GROUP by nazwa). SELECT * FROM zespoly_stat s WHERE

FROM pracownicy NATURAL JOIN zespoly WHERE nazwa = 'SYSTEMY ROZPROSZONE') WHERE etat = 'PROFESOR';.. Modyfikowanie i usuwanie wyniku

• jeśli podano listę nazw atrybutów nowej relacji to lista atrybutów w klauzuli SELECT zapytania musi się pokrywać z tą listą.

• Alternatywa 2.: jeśli dla usuwanego rekordu relacji nadrzędnej istnieją w relacji podrzędnej rekordy powiązane, usunięty zostaje rekord relacji nadrzędnej a w

Operator łączenia, czyli zwykły przecinek, pozwala na deklarowanie w jednej linijce od razu kilka zmiennych tego