Plan zajęć
- Funkcje agregujące i kauzule GROUP BY oraz HAVING
- Operator algebry relacyjnej - iloczyn kartezjański
- Złączenia relacji - operator JOIN
Polecenie ( instrukcja) SELECT umozliwia pobranie danych z bazy danych. W ramach polecenia wyróżniamy odpowiednie części opisane przez słowa kluczowe - klauzule - realizujące określone działania. Poniżej pełna wersja polecenia.
SELECT [DISTINCT] nazwy kolumn, wyrażenia arytmetyczne, funkcje
FROM nazwy tabel lub widoków
WHERE warunek (wybieranie wierszy)
GROUP BY nazwy kolumn
HAVING warunek (grupowanie wybieranych wierszy)
[UNION, INTERSECT, EXCEPT] operacje na zbiorach, służą do łączenia wyników wielu zapytań
ORDER BY nazwy kolumn lub pozycje kolumn [ ASC | DESC]
Do prezentacji możliwości polecenia SELECT wykorzystamy bazę KURS w której do tabeli UCZEST_KURS
dodaliśmy dodatkowe atrybuty: oplata - DECIMAL i ocena - DECIMAL. Diagram ERD zmodyfikowanej bazy został
przedstawiony na rys.1. Odpowiednie polecenia SQL i dane zawarte są skrypcie kurs_update.sql.
Skrypt kurs_update.sql ( [listing dokumentu] [link do dokumentu] )
alter table uczest_kurs add oplata decimal(8,2) ; alter table uczest_kurs add ocena decimal(5,2) ; -- wstawienie danych - tabela uczest_kurs - uczestnicy na kursach -- kurs 1 - angielski 1 gr 1 update uczest_kurs set ( oplata, ocena ) = ( 500., 3 ) where id_kurs=1 and id_uczest=1; update uczest_kurs set ( oplata, ocena ) = ( 500., 4 ) where id_kurs=1 and id_uczest=3; update uczest_kurs set ( oplata, ocena ) = ( 500., 5 ) where id_kurs=1 and id_uczest=5; update uczest_kurs set ( oplata, ocena ) = ( 500., 3 ) where id_kurs=1 and id_uczest=7; update uczest_kurs set ( oplata, ocena ) = ( 500., 4 ) where id_kurs=1 and id_uczest=8; update uczest_kurs set ( oplata, ocena ) = ( 500., 4 ) where id_kurs=1 and id_uczest=10; update uczest_kurs set ( oplata, ocena ) = ( 500., 5 ) where id_kurs=1 and id_uczest=11; update uczest_kurs set ( oplata, ocena ) = ( 500., 3 ) where id_kurs=1 and id_uczest=12; -- kurs 2 - angielski 1 gr 2 update uczest_kurs set ( oplata, ocena ) = ( 500., 3 ) where id_kurs=2 and id_uczest=2; update uczest_kurs set ( oplata, ocena ) = ( 500., 3 ) where id_kurs=2 and id_uczest=16; update uczest_kurs set ( oplata, ocena ) = ( 500., 5 ) where id_kurs=2 and id_uczest=17; update uczest_kurs set ( oplata, ocena ) = ( 500., 3 ) where id_kurs=2 and id_uczest=18; update uczest_kurs set ( oplata, ocena ) = ( 500., 4 ) where id_kurs=2 and id_uczest=20; -- kurs 3 - angielski 2 gr 1 update uczest_kurs set ( oplata, ocena ) = ( 700., 3 ) where id_kurs=3 and id_uczest=1; update uczest_kurs set ( oplata, ocena ) = ( 700., 4 ) where id_kurs=3 and id_uczest=2; update uczest_kurs set ( oplata, ocena ) = ( 700., 5 ) where id_kurs=3 and id_uczest=3; update uczest_kurs set ( oplata, ocena ) = ( 700., 3 ) where id_kurs=3 and id_uczest=5; update uczest_kurs set ( oplata, ocena ) = ( 700., 4 ) where id_kurs=3 and id_uczest=7; update uczest_kurs set ( oplata, ocena ) = ( 700., 4 ) where id_kurs=3 and id_uczest=17; update uczest_kurs set ( oplata, ocena ) = ( 700., 5 ) where id_kurs=3 and id_uczest=18; update uczest_kurs set ( oplata, ocena ) = ( 700., 3 ) where id_kurs=3 and id_uczest=20; -- kurs 4 - angielski 3 gr 1 update uczest_kurs set ( oplata, ocena ) = ( 800., 4 ) where id_kurs=4 and id_uczest=1; update uczest_kurs set ( oplata, ocena ) = ( 800., 4 ) where id_kurs=4 and id_uczest=2; update uczest_kurs set ( oplata, ocena ) = ( 800., 4 ) where id_kurs=4 and id_uczest=3; update uczest_kurs set ( oplata, ocena ) = ( 800., 3 ) where id_kurs=4 and id_uczest=5; update uczest_kurs set ( oplata, ocena ) = ( 800., 3 ) where id_kurs=4 and id_uczest=21; update uczest_kurs set ( oplata, ocena ) = ( 800., 5 ) where id_kurs=4 and id_uczest=22; update uczest_kurs set ( oplata, ocena ) = ( 800., 5 ) where id_kurs=4 and id_uczest=25; -- kurs 5 - angielski 4 gr 1 update uczest_kurs set ( oplata, ocena ) = ( 850., 4 ) where id_kurs=5 and id_uczest=1; update uczest_kurs set ( oplata, ocena ) = ( 850., 4 ) where id_kurs=5 and id_uczest=2; update uczest_kurs set ( oplata, ocena ) = ( 850., 4 ) where id_kurs=5 and id_uczest=3; update uczest_kurs set ( oplata, ocena ) = ( 850., 3 ) where id_kurs=5 and id_uczest=5; update uczest_kurs set ( oplata, ocena ) = ( 850., 3 ) where id_kurs=5 and id_uczest=21; update uczest_kurs set ( oplata, ocena ) = ( 850., 5 ) where id_kurs=5 and id_uczest=22; -- kurs 6 - niemiecki 1 gr 1 update uczest_kurs set ( oplata, ocena ) = ( 600., 4 ) where id_kurs=6 and id_uczest=8; update uczest_kurs set ( oplata, ocena ) = ( 600., 3 ) where id_kurs=6 and id_uczest=9; update uczest_kurs set ( oplata, ocena ) = ( 600., 3 ) where id_kurs=6 and id_uczest=13; update uczest_kurs set ( oplata, ocena ) = ( 600., 3 ) where id_kurs=6 and id_uczest=15; update uczest_kurs set ( oplata, ocena ) = ( 600., 5 ) where id_kurs=6 and id_uczest=19; update uczest_kurs set ( oplata, ocena ) = ( 600., 4 ) where id_kurs=6 and id_uczest=24; update uczest_kurs set ( oplata, ocena ) = ( 600., 4 ) where id_kurs=6 and id_uczest=27; -- kurs 7 - niemiecki 1 gr 2 update uczest_kurs set ( oplata, ocena ) = ( 600., 4 ) where id_kurs=7 and id_uczest=11; update uczest_kurs set ( oplata, ocena ) = ( 600., 4 ) where id_kurs=7 and id_uczest=17; update uczest_kurs set ( oplata, ocena ) = ( 600., 3 ) where id_kurs=7 and id_uczest=18; update uczest_kurs set ( oplata, ocena ) = ( 600., 3 ) where id_kurs=7 and id_uczest=23; update uczest_kurs set ( oplata, ocena ) = ( 600., 5 ) where id_kurs=7 and id_uczest=25; update uczest_kurs set ( oplata, ocena ) = ( 600., 3 ) where id_kurs=7 and id_uczest=28; update uczest_kurs set ( oplata, ocena ) = ( 600., 3 ) where id_kurs=7 and id_uczest=30; -- kurs 8 - niemiecki 2 gr 1 update uczest_kurs set ( oplata, ocena ) = ( 650., 4 ) where id_kurs=8 and id_uczest=8; update uczest_kurs set ( oplata, ocena ) = ( 650., 4 ) where id_kurs=8 and id_uczest=9; update uczest_kurs set ( oplata, ocena ) = ( 650., 3 ) where id_kurs=8 and id_uczest=13; update uczest_kurs set ( oplata, ocena ) = ( 650., 3 ) where id_kurs=8 and id_uczest=15; update uczest_kurs set ( oplata, ocena ) = ( 650., 5 ) where id_kurs=8 and id_uczest=19; update uczest_kurs set ( oplata, ocena ) = ( 650., 3 ) where id_kurs=8 and id_uczest=24; update uczest_kurs set ( oplata, ocena ) = ( 650., 3 ) where id_kurs=8 and id_uczest=27; -- kurs 9 - niemiecki 3 gr 1 update uczest_kurs set ( oplata, ocena ) = ( 800., 4 ) where id_kurs=9 and id_uczest=8; update uczest_kurs set ( oplata, ocena ) = ( 800., 4 ) where id_kurs=9 and id_uczest=9; update uczest_kurs set ( oplata, ocena ) = ( 800., 4 ) where id_kurs=9 and id_uczest=13; update uczest_kurs set ( oplata, ocena ) = ( 800., 5 ) where id_kurs=9 and id_uczest=24; update uczest_kurs set ( oplata, ocena ) = ( 800., 5 ) where id_kurs=9 and id_uczest=27; -- kurs 10 - hiszpanski 1 gr 1 update uczest_kurs set ( oplata, ocena ) = ( 700., 4 ) where id_kurs=10 and id_uczest=6; update uczest_kurs set ( oplata, ocena ) = ( 700., 4 ) where id_kurs=10 and id_uczest=16; update uczest_kurs set ( oplata, ocena ) = ( 700., 4 ) where id_kurs=10 and id_uczest=18; update uczest_kurs set ( oplata, ocena ) = ( 700., 4 ) where id_kurs=10 and id_uczest=22; update uczest_kurs set ( oplata, ocena ) = ( 700., 5 ) where id_kurs=10 and id_uczest=24; update uczest_kurs set ( oplata, ocena ) = ( 700., 3 ) where id_kurs=10 and id_uczest=29; update uczest_kurs set ( oplata, ocena ) = ( 700., 3 ) where id_kurs=10 and id_uczest=30; -- kurs 11 - hiszpanski 2 gr 1 update uczest_kurs set ( oplata, ocena ) = ( 900., 4 ) where id_kurs=11 and id_uczest=6; update uczest_kurs set ( oplata, ocena ) = ( 900., 4 ) where id_kurs=11 and id_uczest=16; update uczest_kurs set ( oplata, ocena ) = ( 900., 4 ) where id_kurs=11 and id_uczest=18; update uczest_kurs set ( oplata, ocena ) = ( 900., 4 ) where id_kurs=11 and id_uczest=22; update uczest_kurs set ( oplata, ocena ) = ( 900., 5 ) where id_kurs=11 and id_uczest=24; update uczest_kurs set ( oplata, ocena ) = ( 900., 3 ) where id_kurs=11 and id_uczest=29; update uczest_kurs set ( oplata, ocena ) = ( 900., 3 ) where id_kurs=11 and id_uczest=30;
Funkcje agregujące w przeciwieństwie do funkcji skalarnych ( działające w ramach jednej krotki) umożliwiają przetworzenie określonej grupy krotek i opracowanie wyniku zgodnie z ich funkcjonalnością.
Standardowe funkcje agregujące dostępne w języku SQL.
Funkcje agregujące mogą działać na wszystkich krotkach relacji lub na wybranych zgodnie z określonym kryterium wykorzystując klauzalę GROUP BY. Zwrócone wyniki możemy dodatkowo przefiltrować wykorzystując słowo kluczowe HAVING.
Przykładowe użycie funkcji agregujących oraz klauzul GROUP BY i HAVING zostanie przedstawione poniżej dla danych zawartych w bazie KURS.
SELECT COUNT(*) FROM uczestnik ;
SELECT SUM(oplata) FROM uczest_kurs ;
SELECT AVG(oplata) FROM uczest_kurs ;
SELECT MAX(oplata) FROM uczest_kurs ;
SELECT MIN(oplata) FROM uczest_kurs ;
SELECT oplata, COUNT(*) FROM uczest_kurs GROUP BY oplata ;
SELECT id_kurs, COUNT(*) FROM uczest_kurs GROUP BY id_kurs ORDER BY 1 ;
SELECT nazwisko, count(*) FROM uczest_kurs, uczestnik WHERE id_uczest = id_uczestnik GROUP BY nazwisko ORDER BY 1;
SELECT nazwisko, count(*) FROM uczest_kurs, uczestnik WHERE id_uczest = id_uczestnik GROUP BY nazwisko HAVING count(*) > 3 ORDER BY 2 DESC, 1;
Złączenie relacji daje w wyniku relację składającą się ze wszystkich możliwych krotek, które są kombinacjami dwu krotek, po jednej z każdej ze wskazanych relacji, takich że mają tę samą wartość wspólnego atrybutu. Do realizacji złączeń wykorzytywany jest operator JOIN. W ramach złączenia istnieją nastepujące rozwiązania: złaczenie naturalne (INNER JOIN) zgodne z równozłączeniem, złączenie typu (CROSS JOIN) zwane złączeniem krzyżowym (iloczyn relacji) oraz złączenie zewnętrzne (lewostronne, prawostronne i pełne) niedostępne z poziomu łączenia tabel z wykorzystaniem kluzuli WHERE.
SELECT { atrybuty }
FROM relacja1 R1 [INNER] JOIN relacja2 R2 ON R1.id = R2.id;
SELECT Kurs.id_kurs, Kurs.id_grupa, Kurs_opis.opis FROM Kurs INNER JOIN Kurs_opis ON Kurs.id_nazwa = Kurs_opis.id_nazwa ;
SELECT Uczestnik.nazwisko, Uczestnik.imie, Kurs_opis.opis, Kurs.id_kurs, Kurs.id_grupa
FROM Kurs JOIN uczest_kurs
ON Kurs.id_kurs = uczest_kurs.id_kurs
JOIN Uczestnik
ON Uczestnik.id_uczestnik = uczest_kurs.id_uczest
JOIN Kurs_opis
ON Kurs.id_nazwa = Kurs_opis.id_nazwa ;
SELECT { atrybuty }
FROM relacja1 R1 LEFT [OUTER] JOIN relacja2 R2 ON R1.id = R2.id;
SELECT w.nazwisko, w.imie, ko.opis
FROM wykladowca w LEFT JOIN wykl_kurs wk ON w.id_wykladowca = wk.id_wykl
LEFT JOIN kurs k USING (id_kurs)
LEFT JOIN kurs_opis ko USING (id_nazwa)
ORDER BY w.nazwisko ;
SELECT { atrybuty }
FROM relacja1 R1 RIGHT [OUTER] JOIN relacja2 R2 ON R1.id = R2.id;
SELECT w.nazwisko, w.imie, ko.opis
FROM wykladowca w RIGHT JOIN wykl_kurs wk ON w.id_wykladowca = wk.id_wykl
RIGHT JOIN kurs k USING (id_kurs)
RIGHT JOIN kurs_opis ko USING (id_nazwa)
ORDER BY ko.opis ;
SELECT { atrybuty }
FROM relacja1 R1 FULL [OUTER] JOIN relacja2 R2 ON R1.id = R2.id;
SELECT w.nazwisko, w.imie, ko.opis
FROM wykladowca w FULL JOIN wykl_kurs wk ON w.id_wykladowca = wk.id_wykl
FULL JOIN kurs k USING (id_kurs)
FULL JOIN kurs_opis ko USING (id_nazwa)
ORDER BY w.nazwisko, ko.opis ;
SELECT nazwisko, imie FROM wykladowca w LEFT JOIN wykl_kurs wk ON w.id_wykladowca = wk.id_wykl WHERE wk.id_wykl IS NULL ORDER BY 1;
SELECT opis FROM kurs k RIGHT JOIN kurs_opis ko ON k.id_nazwa = ko.id_nazwa WHERE k.id_nazwa IS NULL ;
SELECT w.nazwisko, w.imie, ko.opis FROM
wykladowca w FULL JOIN wykl_kurs wk ON w.id_wykladowca = wk.id_wykl
FULL JOIN kurs k USING(id_kurs)
FULL JOIN kurs_opis ko ON k.id_nazwa = ko.id_nazwa
WHERE wk.id_kurs IS NULL OR wk.id_wykl IS NULL;