Microsoft PowerPoint - TBD_ns_w6_2013_14_student [tryb zgodno
Transkrypt
Microsoft PowerPoint - TBD_ns_w6_2013_14_student [tryb zgodno
Funkcje grupowe 2 Funkcje grupowe są przeznaczone do działania na grupach wierszy. Wynikiem działania funkcji grupowej jest pojedyncza wartość dla całej grupy, a nie jedną wartość dla każdego wiersza. Przykłady funkcji: TECHNOLOGIE BAZ DANYCH Wykład 6: Zapytania SQL: grupowanie i podzapytania AVG ([DISTINCT] wyrażenie) COUNT ([DISTINCT] wyrażenie) COUNT(*) MAX ([DISTINCT] wyrażenie) MIN ([DISTINCT] wyrażenie) STDDEV ([DISTINCT] wyrażenie) SUM ([DISTINCT] wyrażenie) VARIANCE ([DISTINCT] wyrażenie) Małgorzata Krętowska Wydział Informatyki PB Wszystkie funkcje grupowe, z wyjątkiem count(*) ignorują NULL. Zasady wykonania zapytania grupującego Zapytania grupujące 3 4 SELECT lista pól FROM tabele WHERE warunki przed grupowaniem GROUP BY pola grupujące HAVING warunki po grupowaniu Rozważ wszystkie kombinacje wierszy tabel występujących w klauzuli FROM Do każdego wiersza zastosuj warunek WHERE Podziel wiersze na grupy Do każdej grupy zastosuj warunek w klauzuli HAVING Dla każdego wiersza reprezenującego grupę oblicz wartości wyrażeń po SELECT Ograniczenia Podzapytania 5 Na liście wyboru polecenia SELECT używającego grupowania wolno umieszczać tylko te kolumny, które są przedmiotem działania klauzuli GROUP BY chyba, że występują one wewnątrz funkcji grupującej. Każda kolumna lub wyrażenie występujące na liście SELECT, nie objęte funkcją grupową, musi być przedmiotem grupowania klauzulą GROUP BY Podzapytania zwracające jeden wiersz Wynikiem jest pojedynczy wiersz. Przykład: Znaleźć pracowników z pensją równą minimalnemu zarobkowi w firmie. Co należy robić po kolei? 1. Znajdujemy minimalną pensję: Podzapytanie - polecenie SELECT zagnieżdżone w innym poleceniu SELECT. Umożliwia konstruowanie zapytania odwołującego się do wartości wybranych przez inne polecenie SELECT. Przykład: SELECT kolumna1, kolumna2,... FROM tabela WHERE kolumna = (SELECT kolumna FROM tabela WHERE warunek) Podzapytania zwracające jeden wiersz Wstawiając zapytanie 1 do 2, otrzymujemy: SQL> select nazwisko, stanowisko, pensja from pracownik where pensja =(select min(pensja) from pracownik); nazwisko SQL> select min(pensja) from pracownik; 6 stanowisko pensja ---------- --------- ---------- MIN(PENSJA) SMITH CLERK 800 ---------800 2. Znajdujemy pracowników o pensji równej wartości obliczonej w pierwszym kroku: select nazwisko, stanowisko, pensja from pracownik where pensja =<wynik poprzedniego zapytania> 7 Przebieg wykonania zapytania: realizacja zapytania wewnętrznego na podstawie wartości zwróconej przez blok wewnętrzny przetwarzany jest blok główny zapytania W przypadku zapytań zwracających jeden wiersz mogą być stosowane zwykłe 8 operatory porównania: =, >, <=,... Sygnalizacja błędów Operatory ANY i ALL Co się stanie, jeżeli podzapytanie zwraca więcej niż jeden wiersz a w warunku zostanie użyty operator do porównywania jednego wyniku? SQL> select nazwisko, pensja, nr_departamentu from pracownik where pensja = (select min(pensja) from pracownik group by nr_departamentu); where pensja = (select min(pensja) from pracownik group by nr_departamentu) * BŁĄD w linii 2: ORA-01427: jednowierszowe podzapytanie zwraca więcej niż jeden wiersz Podobnie jeżeli podzapytanie nie zwróci żadnego wiersza. Opearatory ANY i ALL można stosować w podzapytaniach zwracających więcej niż jeden wiersz. Wykorzystuje się je w klauzulach WHERE I HAVING łącznie z operatorami porównywania (=; !=; <; >; <=; >=) Operator ANY powoduje akceptację (spełnienie warunku) po stwierdzeniu zgodności wyrażenia z którąkolwiek z wartości zwracanych przez podzapytanie Operator ALL służy do porównania z wszystkimi wartościami zwracanymi przez podzapytanie Przed operatorami ANY i ALL można stosować zaprzeczenie NOT 9 Podzapytania - wskazówki Wewnętrzne zapytanie musi być ujęte w nawiasy i musi występować po prawej stronie warunku W podzapytaniu nie wolno stosować klauzuli ORDER BY. Obowiązuje zasada jednej klauzuli ORDER BY dla całego polecenia SELECT. Jeśli jest potrzebna umieszczamy ją jako ostatnią Kolumny występujące na liście wyboru wewnętrznego zapytania muszą występować w kolejności zgodnej z kolejnością kolumn ujętych w nawiasy warunku zapytania głównego. Musi również występować zgodność co do liczby i typu kolumn wybieranych w bloku wewnętrznym i kolumn bloku zewnętrznego porównywanych z nimi. 11 10 Podzapytania zwracające wiele atrybutów Znaleźć pracowników o pensjach z listy najniższych zarobków osiąganych w departamentach. SQL> select nazwisko, pensja, nr_departamentu from pracownik where pensja in (select min(pensja) from pracownik group by nr_departamentu); nazwisko pensja nr_departamentu ---------- ---------- ---------SMITH 800 JAMES 950 20 30 MILLER 1300 10 12 13 Podzapytania zwracające wiele atrybutów W jaki sposób można uzyskać informacje o pracownikach zarabiających najmniej w ich departamentach? (Metoda 1) SQL> select nazwisko, pensja, nr_departamentu from pracownik where (pensja,nr_departamentu) in (select min(pensja), nr_departamentu from pracownik group by nr_departamentu); nazwisko pensja nr_departamentu ---------- ---------- ---------SMITH 800 20 JAMES 950 30 MILLER 1300 10 Uwagi WHERE (kolumna1, kolumna 2...) = (SELECT kol1, kol2...) kolumny w bloku zewnętrznym powinny być ujęte w nawiasy i oddzielone przecinkami powinna być zgodność co do liczby i typu kolumn wybieranych w bloku wewnętrznym i kolumn bloku zewnętrznego porównywanych z nimi 14 Podzapytania skorelowane W jaki sposób można uzyskać informacje o pracownikach zarabiających najmniej w ich departamentach? (Metoda 2) SQL> select nazwisko, pensja, nr_departamentu from pracownik e where pensja = (select min(pensja) from pracownik where e.nr_departamentu=pracownik.nr_departamentu group by nr_departamentu); nazwisko pensja nr_departamentu ---------- ---------- ---------SMITH 800 20 JAMES 950 30 MILLER 1300 10 15 Podzapytania skorelowane uwagi Każdy wiersz proponowany przez zapytanie główne przechodzi „próbę” warunku wyrażonego za pomocą zapytania skorelowanego, w którym występuje odwołanie do wartości kolumn tego wiersza. Wykonanie SELECT z podzapytaniem skorelowanym: pobranie wiersza przez zewnętrzne zapytanie wykonanie wewnętrznego zapytania na podstawie wartości z pobranego w pkt 1. Wiersza zaakceptowanie bądź odrzucenie wiersza na podstawie wyniku zapytania z pkt 2. Powtórzenie akcji opisanych wyżej, aż do wyczerpania wszystkich wierszy proponowanych przez zapytanie zewnętrzne. 16 Zagnieżdżanie zapytań Operator EXISTS Znaleźć pracowników, których zarobki przekraczają najwyższą pensję z departamentu SALES. W przypadku zapytań skorelowanych czasami nie interesuje nas wynik zapytania, ale jedynie czy wiersz o zadanych przez nas warunkach istnieje. Wówczas wykorzystujemy operator EXISTS. SQL> select nazwisko, stanowisko, data_zatrudnienia, pensja from pracownik where pensja> (select max(pensja) from pracownik where nr_departamentu= (select nr_departamentu from departament where nazwa=‘SALES')); nazwisko stanowisko data_zatrudnienia EXISTS (podzapytanie) - zwraca „true” jeżeli podzapytanie zwróci przynajmniej jeden wiersz NOT EXISTS(podzapytanie) zwraca „true” jeżeli podzapytanie nie zwróci żadnego wiersza pensja ---------- --------- -------- ---------JONES MANAGER 81/04/02 SCOTT ANALYST 87/04/19 3000 2975 KING PRESIDENT 81/11/17 5000 FORD ANALYST 81/12/03 3000 Nie istnieje ograniczenie poziomów zagnieżdżenia. 17 18 Podzapytania po FROM Podzapytania po FROM 20 Podzapytania mogą występować po WHERE , HAVING, SELECT i FROM: FROM tabela1, (podzapytanie1) alias1, (podzapytanie2) alias2... Policzyć jaki procent pracowników pracuje w poszczególnych działach firmy. Podać nazwę działu i procent pracowników. Liczba pracowników w poszczególnych działach SQL> select nazwa, count(id_pracownika) x from pracownik, departament where pracownik.nr_departamentu (+) = departament.nr_departamentu group by nazwa, departament.nr_departamentu; nazwa X -------------- ---------- 19 ACCOUNTING 3 RESEARCH 5 SALES 6 OPERATIONS 0 Przykład cd Liczba wszystkich pracowników SQL> select count(*) y from pracownik; Y ---------14 Całe zapytanie: SQL> select A.nazwa, (A.x/B.y)*100 procent from (select nazwa, count(id_pracownika) x from pracownik, departament where pracownik.nr_departamentu (+) = departament.nr_departamentu group by nazwa, departament.nr_departamentu) A, (select count(*) y from pracownik) B; nazwa PROCENT -------------- ---------ACCOUNTING 21,4285714 RESEARCH 35,7142857 SALES 42,8571429 OPERATIONS 0 21