1. Zaªó» tabel logika o trzech atrybutach p,q,r typu BOOLEAN. Uzupeªnij j wszystkimi mo»liwymi waluacjami logiki SQL (oczywi±cie nie rób tego r cznie). Nast pnie przy u»yciu komend SQLa sprawd¹, dla jakich waluacji formuªa zdaniowa ((p q) (q IS NULL)) IS NULL r przyjmuje warto± NULL. W ten sposób przekonaj si, czy jest ona tautologi w logice SQL. CREATE TABLE logika (p BOOLEAN); INSERT INTO logika VALUES(true); INSERT INTO logika VALUES(false); INSERT INTO logika VALUES(NULL); SELECT L1.p AS p, L2.p AS r, L3.p AS q FROM logika AS L1, logika AS L2, logika AS L3 WHERE ((((L1.p AND (NOT L3.p)) OR (L3.p IS NULL)) IS NULL) AND (NOT L2.p)) IS NULL; 2. Baza danych opisuj ca struktur pewnej rmy ma nast puj cy schemat: pracownicy (nr_pracownika INTEGER, imie TEXT, nazwisko TEXT, stanowisko TEXT, opis TEXT, przelozony INTEGER, data_zatrudnienia DATE, pensja DECIMAL(7,2), prowizja DECIMAL(7,2), nr_wydzialu INTEGER) wydzialy (nr_wydzialu INTEGER, nazwa INTEGER, lokalizacja TEXT) pensje (nr_przedzialu INTEGER, dolna_granica DECIMAL(7,2), gorna_granica DECIMAL(7,2)) Napisz zapytania realizuj ce nast puj ce zadania: (a) wyznacz list pracowników, których nazwisko zaczyna si liter K i zostali zatrudnieni przed 1998 r. Uporz dkuj list wg daty zatrudnienia w porz dku malejacym, \i Dokumenty/semestr.3/Bazy.Danych/lista2/firma.sql SELECT imie, nazwisko FROM pracownicy WHERE (nazwisko >'K') AND (nazwisko < 'L') AND (data_zatrudnienia < '1998-01-01') ORDER BY data_zatrudnienia DESC; (b) wyznacz list pracowników, którzy pracuj na stanowisku dyrektor w miastach Pozna«lub Toru«, SELECT imie, nazwisko FROM pracownicy, wydzialy WHERE pracownicy.nr_wydzialu=wydzialy.nr_wydzialu AND pracownicy.stanowisko='dyrektor' AND (wydzialy.lokalizacja='poznan' OR wydzialy.lokalizacja='torun'); (c) wyznacz list osób, których zarobki znajduj si w drugim przedziale pensji. Uporz dkuj wg miejsca pracy, SELECT pracownicy.imie AS imie, pracownicy.nazwisko AS nazwisko FROM pracownicy, wydzialy, pensje WHERE pracownicy.nr_wydzialu=wydzialy.nr_wydzialu AND pensje.nr_przedzialu=2 1
Bazy danych AND pensje.dolna_granica <= pracownicy.pensja AND pracownicy.pensja <= pensje.gorna_granica ORDER BY wydzialy.lokalizacja DESC; (d) wyznacz nazwiska pracowników, którzy pracuj w tych samych wydziaªach, co ich przeªo»eni. Obok nazwiska pracownika umie± nazwisko przeªo»onego i nr wydziaªu, w którym obaj pracuj, SELECT pracownicy.imie AS imie, pracownicy.nazwisko AS nazwisko, przelozeni.nazwisko AS przelozony, pracownicy.nr_wydzialu AS numer_wydzialu FROM pracownicy, pracownicy AS przelozeni WHERE pracownicy.przelozony=przelozeni.nr_pracownika AND pracownicy.nr_wydzialu=przelozeni.nr_wydzialu; (e) wyznacz stanowiska (bez powtórze«), na których nie ma prowizji. Uporz dkuj wynik wg liczby liter w stanowisku (wskazówka: dªugo± napisu jest zwracana przez funkcj length, a ko«cowe spacje mo»na usun funkcj rtrim), SELECT stanowisko FROM pracownicy WHERE prowizja > 0 OR prowizja IS NULL GROUP BY stanowisko ORDER BY length(rtrim(stanowisko)); (f) ustaw w pary pracowników, którzy pracuj w tym samym wydziale. powinny by ró»ne i pary nie powinny si powtarza, Nazwiska w parach SELECT pracownicy1.nazwisko AS nazwisko, pracownicy2.nazwisko AS nazwisko, pracownicy1.nr_wydzialu AS nr_wydzialu FROM pracownicy AS pracownicy1, pracownicy AS pracownicy2 WHERE pracownicy1.nr_wydzialu=pracownicy2.nr_wydzialu AND pracownicy1.nr_pracownika < pracownicy2.nr_pracownika; 3. U»ywaj c pliku poset.sql utwórz tabel p opisuj c pewn relacj dwuargumentow. Przy pomocy komend SQLa: (a) wypisz wszystkie liczby wyst puj ce w p; oznaczmy zbiór tych liczb przez d; \i Dokumenty/semestr.3/Bazy.Danych/lista2/poset.sql INSERT INTO d (SELECT x FROM p UNION SELECT y FROM p); (b) traktuj c p jako relacj na d sprawd¹, czy jest ona zwrotna; SELECT z FROM d SELECT x FROM p WHERE p.x=p.y; (c) nie oszukujmy si nie jest zwrotna; popraw p tak, by byªa zwrotna na d; CREATE TABLE p2 (x INTEGER, y INTEGER); INSERT INTO p2 (SELECT * FROM p UNION SELECT z,z FROM d); 2
i sprawdzenie SELECT z FROM d SELECT x FROM p2 WHERE p2.x=p2.y; (d) sprawd¹,»e tak poprawiona p jest cz ±ciowym porz dkiem na d; przechodznio± SELECT raz.x, raz.y, dwa.y FROM p2 AS raz, p2 AS dwa WHERE raz.y=dwa.x SELECT raz.x, raz.y, dwa.y FROM p2 AS raz, p2 AS dwa, p2 AS trzy WHERE raz.y=dwa.x AND raz.x=trzy.x AND dwa.y=trzy.y; sªaba antysymetria SELECT * FROM p2 AS raz, p2 AS dwa WHERE raz.x=dwa.y AND raz.y=dwa.x AND raz.x!=raz.y; (e) wylicz, ile jest elementów maksymalnych w (d, p). SELECT count(*) FROM ((SELECT x as d FROM p UNION SELECT y FROM p) SELECT x AS d FROM p WHERE x!= y) AS a; 4. Pewna ksi garnia ma baz danych zgodn z nast puj cym schematem: autorzy (nr_autora INTEGER, imie TEXT, nazwisko TEXT) ksiazki (isbn TEXT, wydawca TEXT, tytul TEXT, rok_wydania INTEGER) egzemplarze (nr_egzemplarza INTEGER, isbn TEXT) autorstwa (isbn TEXT, nr_autora INTEGER) tematy (nr_tematu INTEGER, nazwa TEXT, wyjasnienie TEXT) na_temat (isbn TEXT, nr_tematu INTEGER) Napisz zapytania realizuj ce nast puj ce zadania: (a) wypisz nazwiska autorów, którzy napisali przynajmniej jedn ksi»k na temat baz danych, 3
Bazy danych (b) \i Dokumenty/semestr.3/Bazy.Danych/lista2/ksiegarnia.sql SELECT autorzy.imie, autorzy.nazwisko FROM autorzy, autorstwa, na_temat, tematy WHERE autorzy.nr_autora=autorstwa.nr_autora AND autorstwa.isbn = na_temat.isbn AND na_temat.nr_tematu=tematy.nr_tematu AND tematy.nazwa= 'bazy danych' GROUP BY autorzy.imie, autorzy.nazwisko; (c) wypisz numery tematów, w których zakresie znajduj si ksia»ki, których autorzy napisali przy- najmniej jedn ksi»k z psychologii, SELECT na_temat.nr_tematu FROM ( SELECT autorzy.nr_autora AS autor FROM autorzy, autorstwa, na_temat, tematy WHERE autorzy.nr_autora=autorstwa.nr_autora AND autorstwa.isbn = na_temat.isbn AND na_temat.nr_tematu=tematy.nr_tematu AND tematy.nazwa= 'psychologia') AS numery, autorstwa, na_temat WHERE na_temat.isbn=autorstwa.isbn AND autorstwa.nr_autora=numery.autor GROUP BY na_temat.nr_tematu; (d) wyznacz nazwiska autorów, ktorzy wydali przynajmniej jedn ksi»k przed rokiem 2000, (e) SELECT autorzy.nazwisko AS nazwisko FROM ksiazki, autorstwa, autorzy WHERE ksiazki.rok_wydania < 2000 AND ksiazki.isbn=autorstwa.isbn AND autorstwa.nr_autora=autorzy.nr_autora GROUP BY nazwisko; (f) wypisz tytuªy ksi»ek wydanych w roku 1999, SELECT tytul FROM ksiazki WHERE rok_wydania = 1999; (g) sprawd¹, czy w±ród ksi»ek znajduje si taka, której»adnego egzemplarza nie ma obecnie w ksi - garni, SELECT ksiazki.isbn AS isbn, ksiazki.tytul AS tytul, ksiazki.wydawca AS wydawca, ksiazki.rok_wydania AS rok_wydania FROM (SELECT isbn FROM ksiazki SELECT isbn FROM egzemplarze) AS id, ksiazki WHERE ksiazki.isbn=id.isbn; (h) klient chce kupi Frankensteina Mary Shelley. Sprawd¹, czy taka ksi»ka jest na skªadzie i je±li jest, zaktualizuj baz o informacj o sprzeda»y jednego egzemplarza (oczywi±cie zakªadamy,»e klient»yczy sobie najnowsze z dost pnych wyda«). CREATE VIEW do_sprzedazy AS SELECT ksiazki.tytul AS tytul, ksiazki.isbn AS isbn, autorzy.imie AS imie, autorzy.nazwisko AS nazwisko, 4
ksiazki.rok_wydania AS rok, egzemplarze.nr_egzemplarza AS numer FROM egzemplarze, ksiazki, autorstwa, autorzy WHERE egzemplarze.isbn=ksiazki.isbn AND ksiazki.isbn=autorstwa.isbn AND autorstwa.nr_autora=autorzy.nr_autora AND ksiazki.tytul='frankenstein' AND autorzy.imie='mary' AND autorzy.nazwisko='shelley' GROUP BY rok, tytul, ksiazki.isbn, imie, nazwisko, numer; CREATE VIEW numerek AS SELECT do_sprzedazy.numer AS nr FROM do_sprzedazy, (SELECT MAX(rok) AS m FROM do_sprzedazy) AS max WHERE rok=max.m; DELETE FROM egzemplarze WHERE nr_egzemplarza=20; 5