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