Plan zajęć
- Operatory zbiorowe: UNION, INTERSECT, EXCEPT
- Podzapytania - niepowiązane i powiązane
- Podzapytania - operatory ALL, ANY i EXISTS
- Widok (perspektywa, kwerenda)
- Widok modyfikowalny
W ramach operatorów działających na zbiorach wyróżniamy polecenia w języku SQL, które działają na co najmniej dwóch oddzielnych poleceniach SQL. Jeżeli mamy dwa zbiory danych możemy wyróżnić następujące metody wybrania danych:
SELECT a1, a2, a3 FROM R1 UNION [ALL] SELECT a1, a2, a3 FROM R2;
SELECT a1, a2, a3 FROM R1 INTERSECT SELECT a1, a2, a3 FROM R2;
SELECT a1, a2, a3 FROM R1 EXCEPT SELECT a1, a2, a3 FROM R2 ;
Występujące w poleceniach relacje (tabele) muszą mieć zgodną liczbę atrybutów oraz domeny poszczególnych atrybutów muszą być zgodne.
Przykłady wykorzystania operatorów UNION, EXCEPT i INTERSECT w bazie danych KURS.
SELECT imie, nazwisko, 'U' FROM uczestnik UNION SELECT imie, nazwisko, 'W' FROM wykladowca ORDER BY 3,2 ;
SELECT imie, nazwisko FROM wykladowca EXCEPT SELECT imie, nazwisko FROM wykladowca w JOIN wykl_kurs wk ON w.id_wykladowca = wk.id_wykl ORDER BY 2;
SELECT imie, nazwisko FROM wykladowca w LEFT JOIN wykl_kurs wk ON w.id_wykladowca = wk.id_wykl WHERE wk.id_wykl is null ;
SELECT imie, nazwisko FROM uczestnik u JOIN uczest_kurs uk ON u.id_uczestnik = uk.id_uczest where id_kurs in (1,2 ) INTERSECT SELECT imie, nazwisko FROM uczestnik u JOIN uczest_kurs uk ON u.id_uczestnik = uk.id_uczest where id_kurs = 3 ORDER BY 2 ;
Termin podzapytanie używamy do określenia kompletnego polecenia SELECT otoczonego nawiasami i zazwyczaj nazywanego aliasem za pomocą klauzuli AS poza nawiasami. Podzapytania możemy użyć w innym poleceniu SELECT, UPDATE, INSERT czy DELETE. W zależności od zwróconego wyniku podzapytania można go wykorzystać w różnych miejscach podstawowego zapytania.
Kolejnym formalizmem związanym z podzapytaniami są podzapytania skorelowane i nieskorelowane.
Podzapytania można też rozpatrywać ze względu na miejsce wykorzystania.
Przykłady wykorzystania podzapytań w bazie danych KURS.
SELECT i, n FROM ( select imie i, nazwisko n FROM uczestnik ) AS u ORDER BY n ;
SELECT imie, nazwisko FROM uczestnik WHERE id_uczestnik IN ( SELECT id_uczest FROM uczest_kurs WHERE id_kurs=1 ) ORDER BY 2;
SELECT (SELECT COUNT(*) FROM uczestnik ) AS l_uczest, (SELECT COUNT(*) FROM wykladowca ) AS l_wykl, (SELECT COUNT(*) FROM kurs ) AS l_kurs, (SELECT SUM(oplata) FROM uczest_kurs ) AS sum_oplata ;
SELECT ko.opis, ( SELECT COUNT(*) FROM uczest_kurs uk WHERE uk.id_kurs=k.id_kurs ) AS l_ucz, ( SELECT SUM(oplata) FROM uczest_kurs uk WHERE uk.id_kurs=k.id_kurs ) AS s_opl FROM kurs k JOIN kurs_opis ko ON k.id_nazwa = ko.id_kurs;
SELECT ko.opis FROM kurs k JOIN kurs_opis ko ON k.id_nazwa = ko.id_kurs WHERE ( SELECT SUM(oplata) FROM uczest_kurs uk WHERE uk.id_kurs=k.id_kurs ) > 5500;
SELECT ko.opis, k.id_kurs, k.id_grupa FROM kurs k JOIN kurs_opis ko ON k.id_nazwa = ko.id_kurs JOIN uczest_kurs uk ON uk.id_kurs=k.id_kurs GROUP BY ko.opis, k.id_kurs, k.id_grupa HAVING SUM(uk.oplata) > 5500;
Operatory EXISTS, ALL i ANY ( SOME ) wykorzystuje się do analizy danych zwróconych przez podzapytanie (zapytanie wewnętrzne).
SELECT { atrybuty } FROM relacja1 R1
WHERE EXISTS
( SELECT 1 FROM relacja2 R2 WHERE R1.fk = R2.id ) ;
SELECT { atrybuty } FROM relacja1 R1
WHERE NOT EXISTS
( SELECT 1 FROM relacja2 R2 WHERE R1.fk = R2.id ) ;
SELECT { atrybuty } FROM relacja1 R1
WHERE {atrybut} {operator porównania}
( SELECT {R2.atrybut} FROM relacja2 R2 WHERE R1.fk = R2.id ) ;
SELECT { atrybuty } FROM relacja1 R1
WHERE {atrybut} {operator porównania}
( SELECT {R2.atrybut} FROM relacja2 R2 WHERE R1.fk = R2.id ) ;
Przykłady wykorzystania predykatów: ANY, ALL i EXISTS w bazie danych KURS.
SELECT u.imie, u.nazwisko FROM uczestnik u WHERE u.id_uczestnik = ANY ( SELECT id_uczest FROM uczest_kurs ) ORDER BY 2 ;
SELECT u.imie, u.nazwisko FROM uczestnik u WHERE 5 = ALL ( SELECT ocena FROM uczest_kurs uk WHERE uk.id_uczest = u.id_uczestnik ) ORDER BY 2;
SELECT w.imie, w.nazwisko, ko.opis
FROM wykladowca w, kurs_opis ko
WHERE EXISTS ( SELECT 1 FROM wykl_kurs wk JOIN kurs k
ON wk.id_kurs = k.id_kurs
WHERE wk.id_wykl = w.id_wykladowca
AND ko.id_kurs=k.id_nazwa)
ORDER BY 2;
SELECT w.imie, w.nazwisko FROM wykladowca w WHERE NOT EXISTS ( SELECT 1 FROM wykl_kurs wk WHERE wk.id_wykl = w.id_wykladowca ) ORDER BY 2;
Widok jest wynikiem realizacji jednej lub wielu operacji na tabelach w bazie danych tworzących nową dynamiczną tabelę wynikową. Widok jest tabelą wirtualną, która nie musi fizycznie istnieć w bazie danych (w przeciwieństwie do widoków zmaterializowanych). Jest wyliczana na żądanie użytkownika. Dla użytkownika widok wygląda jak zwykła tabela. Widok tworzymy w następujących sytuacjach:
Widok tworzymy poleceniem CREATE VIEW.
CREATE VIEW <nazwa perspektywy> [<nazwa kolumny>,...] AS <zapytanie SELECT definiujące perspektywę> [ WITH [CASCADED|LOCAL] CHECK OPTION]
Widok jest modyfikowalny, jeżeli istnieje możliwość przeniesienia każdego zmodyfikowanego wiersza czy kolumny z perspektywy do tabeli bazowej. Standard ISO narzuca na widoki modyfikowalne ograniczenia:
W ramach polecenia tworzącego widok występują dodatkowe parametry związane z modyfikacją danych poprzez widok.