Grupowanie, złączenia i podzapytania - Wydział Matematyki i ...

Grupowanie, złączenia i podzapytania - Wydział Matematyki i ... Grupowanie, złączenia i podzapytania - Wydział Matematyki i ...

users.mat.umk.pl
from users.mat.umk.pl More from this publisher
19.11.2014 Views

Grupowanie i funkcje agregujące Zadanie 1. Stwórz odpowiednią tabelę Test_agr i wprowadź odpowiednie rekordy tak, aby wynik zapytania SELECT AVG(kol) avg_all, AVG(DISTINCT kol) avg_dist, COUNT(*) count_gw, COUNT(kol) count, COUNT(DISTINCT kol) count_dist, SUM(kol) sum_all, SUM(DISTINCT kol) sum_dist FROM Test_agr; zawierał parami różne liczby. Odp: CREATE TABLE Test_agr ( nazwa VARCHAR(20), kol NUMBER ); INSERT INTO Test_agr VALUES ('nazwa1','10'); INSERT INTO Test_agr VALUES ('nazwa1','20'); INSERT INTO Test_agr VALUES ('nazwa2','20'); INSERT INTO Test_agr VALUES ('nazwa2','30'); INSERT INTO Test_agr VALUES ('nazwa2','40'); INSERT INTO Test_agr (nazwa) VALUES ('nazwa3'); Zadanie 2. W której linii jest błąd? SELECT film_id "ID filmu", tytul AS "Tytuł", tytul AS Tytuł FROM Filmy WHERE budzet > 10 AND "ID filmu" > 2 ORDER BY "ID filmu"; Odp: 4. Alias kolumny nie może być użyty w klauzuli WHERE. W ORDER BY możemy go użyć. SELECT film_id "ID filmu", tytul AS "Tytuł", tytul AS Tytul FROM Filmy WHERE budzet > 10

<strong>Grupowanie</strong> i funkcje agregujące<br />

Zadanie 1. Stwórz odpowiednią tabelę Test_agr i wprowadź odpowiednie<br />

rekordy tak, aby wynik zapytania<br />

SELECT<br />

AVG(kol) avg_all,<br />

AVG(DISTINCT kol) avg_dist,<br />

COUNT(*) count_gw,<br />

COUNT(kol) count,<br />

COUNT(DISTINCT kol) count_dist,<br />

SUM(kol) sum_all,<br />

SUM(DISTINCT kol) sum_dist<br />

FROM Test_agr;<br />

zawierał parami różne liczby.<br />

Odp:<br />

CREATE TABLE Test_agr<br />

( nazwa VARCHAR(20),<br />

kol NUMBER<br />

);<br />

INSERT INTO Test_agr VALUES ('nazwa1','10');<br />

INSERT INTO Test_agr VALUES ('nazwa1','20');<br />

INSERT INTO Test_agr VALUES ('nazwa2','20');<br />

INSERT INTO Test_agr VALUES ('nazwa2','30');<br />

INSERT INTO Test_agr VALUES ('nazwa2','40');<br />

INSERT INTO Test_agr (nazwa) VALUES ('nazwa3');<br />

Zadanie 2. W której linii jest błąd?<br />

SELECT film_id "ID filmu", tytul AS "Tytuł", tytul AS Tytuł<br />

FROM Filmy<br />

WHERE budzet > 10<br />

AND "ID filmu" > 2<br />

ORDER BY "ID filmu";<br />

Odp: 4. Alias kolumny nie może być użyty w klauzuli WHERE. W ORDER BY<br />

możemy go użyć.<br />

SELECT film_id "ID filmu", tytul AS "Tytuł", tytul AS Tytul<br />

FROM Filmy<br />

WHERE budzet > 10


AND film_id > 2<br />

ORDER BY "ID filmu";<br />

Zadanie 3. Który operator A-D może zastąpić OR w poniższym zapytaniu:<br />

SELECT film_id, tytul<br />

FROM Filmy<br />

WHERE film_id = 2 OR film_id = 6;<br />

A. IN<br />

B. BETWEEN .. AND ..<br />

C. LIKE<br />

D. =<br />

Odp: A. WHERE film_id IN (2,6)<br />

Zadanie 4. Które z poniższych SQL zapytań z tabeli Pracownicy(imie,<br />

nazwisko, pensja, wydzial, data_zatrudnienia)<br />

zwraca imie, nazwisko i pensje pracownikow z wydzialu 4.<br />

A. SELECT imie nazwisko pensja<br />

FROM Pracownicy<br />

ORDER BY nazwisko<br />

WHERE wydzial = 4;<br />

B. SELECT imie, nazwisko, pensja<br />

FROM Pracownicy<br />

ORDER BY nazwisko ASC<br />

WHERE wydzial = 4;<br />

C. SELECT imie nazwisko pensja<br />

FROM Pracownicy<br />

WHERE wydzial = 4<br />

ORDER BY nazwisko ASC;<br />

D. SELECT imie, nazwisko, pensja<br />

FROM Pracownicy<br />

WHERE wydzial = 4<br />

ORDER BY nazwisko;<br />

E. SELECT imie, nazwisko, pensja<br />

FROM TABLE Pracownicy<br />

WHERE wydzial IS 4<br />

ORDER BY nazwisko ASC;


Odp: D<br />

CREATE TABLE Pracownicy<br />

( imie VARCHAR(20),<br />

nazwisko VARCHAR(20),<br />

pensja NUMBER,<br />

wydzial NUMBER,<br />

data_zatrudnienia DATE<br />

);<br />

Zadanie 5. Znajdź błąd w poniższym zapytaniu i popraw.<br />

SELECT tytul, AVG(ALL dochod)<br />

,count(*) "liczba filmow"<br />

from Filmy<br />

where film_id > 0<br />

and count(*) > 4<br />

group by studio_id<br />

order by "liczba filmow" DESC;<br />

Odp:<br />

SELECT studio_id, AVG(ALL dochod)<br />

,count(*) "liczba filmow"<br />

FROM Filmy<br />

wHERE film_id > 0<br />

GROUP BY studio_id<br />

HAVING count(*) > 4<br />

ORDER BY "liczba filmow" DESC;<br />

Można też tak:<br />

SELECT studio_id, AVG(ALL dochod)<br />

,count(*) "liczba filmow"<br />

FROM Filmy<br />

wHERE film_id > 0<br />

GROUP BY studio_id<br />

HAVING count(*) > 4<br />

ORDER BY 3 DESC;<br />

ale tak już nie zadziała (dlaczego ?):<br />

SELECT studio_id, AVG(ALL dochod)<br />

,count(*) "liczba filmow"<br />

FROM Filmy<br />

wHERE film_id > 0


GROUP BY studio_id<br />

HAVING "liczba filmow" > 4<br />

ORDER BY 3 DESC;<br />

Zadanie 6. Porównaj zapytania, które są błędne i dlaczego?<br />

SELECT MIN(wiek), MAX(wiek)<br />

FROM Ludzie;<br />

SELECT MIN(wiek), MAX(wiek)<br />

FROM Ludzie<br />

GROUP BY kraj;<br />

SELECT kraj, MIN(wiek), MAX(wiek)<br />

FROM Ludzie<br />

GROUP BY kraj;<br />

SELECT kraj, MIN(wiek), MAX(wiek)<br />

FROM Ludzie<br />

GROUP BY wiek;<br />

SELECT MIN(wiek), MAX(wiek)<br />

FROM Ludzie<br />

GROUP BY wiek;<br />

Zadanie 7. Dlaczego poniższe zapytanie nie jest poprawne?<br />

SELECT nazwisko Nazwisko2, MAX(wiek)<br />

FROM Ludzie<br />

WHERE LOWER(nazwisko) LIKE '%ski%'<br />

GROUP BY kraj<br />

HAVING COUNT(*) > 2;<br />

A. GROUP BY nie zawiera kolumny.<br />

B. Warunek COUNT(*) > 20 powinien być w klauzuli WHERE.<br />

C. GROUP BY musi zawierać funkcje agregującą użytą na liście SELECT.<br />

D. HAVING może zawierać tylko funkcje agregujące użyte na liście SELECT.<br />

Odp: A. GROUP BY musi zawierać kolumnę względem, której jest grupowanie.<br />

Nie można użyć aliasów.<br />

SELECT nazwisko Nazwisko, MAX(wiek)<br />

FROM Ludzie<br />

WHERE LOWER(nazwisko) LIKE '%ski%'<br />

GROUP BY kraj, nazwisko;


Zadanie 9. Czy poprawne jest poniższe zapytanie?<br />

SELECT max(wiek)<br />

FROM Ludzie<br />

WHERE min(wiek) > 15;<br />

Odp: Nie. Nie można używać funkcji agregujących w klauzuli WHERE.<br />

Zadanie 10. Czy poprawne jest poniższe zapytanie?<br />

SELECT nazwisko, AVG(distinct wiek)<br />

,COUNT(kraj) kraj_count<br />

FROM Ludzie<br />

WHERE upper(imie) like 'j%'<br />

OR ABS(wiek) > 10<br />

having COUNT(kraj) > 5<br />

ORDER BY 2 DESC;<br />

Odp: Nie. Istnieje kolumna nazwisko, która nie jest stałą, ani funkcją<br />

grupującą, a więc GROUP BY jest obowiązkowe.<br />

SELECT nazwisko, AVG(distinct wiek)<br />

,COUNT(kraj) kraj_count<br />

FROM Ludzie<br />

WHERE upper(imie) like 'j%'<br />

OR ABS(wiek) > 10<br />

GROUP BY nazwisko<br />

having COUNT(kraj) > 5<br />

ORDER BY 2 DESC;<br />

Ponadto należy zwrócić uwagę na wyrażenie "upper(imie) like 'j%'". To nie jest<br />

błąd w języku SQL, lecz wynik tego zapytania będzie zawsze pusty. Powinno<br />

być upper(imie) like 'J%'.


Złączenia i <strong>podzapytania</strong><br />

Złączenia<br />

SELECT tytul, imie, nazwisko<br />

FROM Filmy, Ludzie;<br />

SELECT tytul, imie, nazwisko<br />

FROM Filmy, Ludzie<br />

WHERE director_id=person_id;<br />

SELECT Filmy.tytul, Ludzie.imie, Ludzie.nazwisko<br />

FROM Filmy, Ludzie<br />

WHERE Filmy.director_id=Ludzie.person_id;<br />

SELECT F.tytul, L.imie, L.nazwisko<br />

FROM Filmy F, Ludzie L<br />

WHERE F.director_id=L.person_id;<br />

Zadanie 1. Wyświetlić filmy, w których dochód był mniejszy niż pensja<br />

pojedynczego aktora<br />

SELECT tytul, person_id, dochod, pensja<br />

FROM Filmy, Obsada<br />

WHERE Filmy.film_id=Obsada.film_id<br />

AND Obsada.pensja > Film.dochod;<br />

Aliasy do tabel:<br />

SELECT DISTINCT P1.person_id, P1.imie, P1.nazwisko<br />

FROM Ludzie P1, Ludzie P2<br />

WHERE P1.kraj=P2.kraj<br />

AND P1.person_id != P2.person_id;<br />

Zadanie 2. Wyświetlić obsadę dowolnie wybranego filmu (np. Rambo)<br />

SELECT imie, nazwisko, rola<br />

FROM Filmy F, Ludzie L, Obsada O<br />

WHERE F.film_id=O.film_id<br />

AND L.person_id=O.person_id<br />

AND F.tytul="Rambo";


Złączenia LEFT JOIN, RIGHT JOIN:<br />

SELECT imie, nazwisko, tytul<br />

FROM Ludzie, Filmy<br />

WHERE person_id=director_id;<br />

SELECT imie, nazwisko, tytul<br />

FROM Ludzie LEFT JOIN Filmy<br />

ON person_id =director_id;<br />

SELECT imie, nazwisko, tytul<br />

FROM Ludzie RIGHT JOIN Filmy<br />

ON person_id =director_id;<br />

Suma: UNION<br />

SELECT studio_id, kraj<br />

FROM Studia<br />

UNION<br />

SELECT person_id, kraj<br />

FROM Ludzie;<br />

Podzapytania. Na poziomie WHERE lub HAVING stosujemy operatory:<br />

=,, IN, NOT IN, EXISTS, NOT EXISTS, ANY, ALL<br />

Zadanie. Wyświetlić tytuł filmu o maksymalnym dochodzie<br />

to nie zadziala (dlaczego?):<br />

SELECT tytul, MAX(dochod)<br />

FROM Filmy;<br />

to nie jest rozwiązaniem<br />

SELECT MAX(dochod)<br />

FROM Filmy;<br />

rozwiazanie<br />

SELECT tytul<br />

FROM Filmy<br />

WHERE dochod = (SELECT MAX(dochod) FROM Filmy);<br />

Poniższe podzapytanie<br />

SELECT tytul<br />

FROM Filmy<br />

WHERE director_id IN ( SELECT person_id<br />

FROM Ludzie<br />

WHERE Ludzie.kraj='PL' );


jest równoważne z<br />

SELECT tytul<br />

FROM Filmy, Ludzie<br />

WHERE director_id=person_id<br />

AND Ludzie.kraj='PL';<br />

SELECT S.nazwa<br />

FROM Studia S<br />

WHERE NOT EXISTS (SELECT tytul<br />

FROM Filmy<br />

WHERE studio_id=S.studio_id);<br />

SELECT imie, nazwisko<br />

FROM Ludzie L<br />

WHERE 10 (SELECT avg(budzet)<br />

FROM Filmy);<br />

2. Studia filmowe, które wyprodukowały filmy, gdzie aktorom wypłacono więcej<br />

pieniędzy niż cały wypracowany przez film przychód:<br />

SELECT nazwa<br />

FROM Studia<br />

WHERE studio_id IN (SELECT studio_id<br />

FROM Filmy<br />

WHERE budzet < (SELECT SUM(pensja)<br />

FROM Obsada<br />

WHERE Filmy.film_id=film_id)<br />

);


Zadanie 5. Zapoznać się z poniższymi zapytaniami i zinterpretować ich<br />

działanie<br />

SELECT film_id, SUM(pensja)<br />

FROM Obsada O<br />

GROUP BY film_id<br />

HAVING SUM(pensja) > (SELECT budzet<br />

FROM Filmy<br />

WHERE film_id=O.film_id);<br />

DELETE FROM Filmy<br />

WHERE budzet < (SELECT SUM(pensja)<br />

FROM Obsada<br />

WHERE Filmy.film_id=film_id);<br />

UPDATE Filmy<br />

SET budzet=budzet*3<br />

WHERE studio_id IN (SELECT studio_id<br />

FROM Studia<br />

WHERE kraj='PL');<br />

INSERT INTO Studia<br />

(studio_id,nazwa,miasto,kraj)<br />

VALUES (25,'Moje Studio','Torun',(SELECT kraj<br />

FROM Ludzie<br />

WHERE person_id=1));<br />

Widoki (perspektywy):<br />

CREATE VIEW Film_rezyser<br />

AS<br />

SELECT tytul,director_id<br />

FROM Filmy;<br />

SELECT *<br />

FROM Film_rezyser;<br />

CREATE VIEW Film_rezyser (tytul,rezyser)<br />

AS<br />

SELECT tytul,director_id<br />

FROM Filmy;


Zadania<br />

Zadanie 1. Utwórz w SQL perpektywę, która zawiera tylko nazwy studiów<br />

filmowych, w których łączny budżet wyprodukowanych filmów jest większy niż<br />

10.<br />

Zadanie 2. Dane są trzy tabele<br />

Przedmioty(kod_p, nazwa, prowadzacy)<br />

Studenci(nr_indeks, nazwisko, wydzial)<br />

Egzaminy(nr_indeks, kod_p, ocena)<br />

Utwórz powyższe tabele uwzględniając klucze główne. W tabeli egzaminy<br />

określ klucze obce.<br />

Zadanie 3. Utwórz w SQL zapytanie, które znajduje nazwiska wszystkich<br />

studentów, którzy nie otrzymali z żadnego egzaminu oceny > 4.<br />

Zadanie 4. Utwórz w SQL zapytanie, które dla każdego przedmiotu podaje<br />

jego nazwę i ilość osób, które zdawały egzamin z tego przedmiotu.<br />

Zadanie 5. Utwórz w SQL perspektywę, która dla każdego przedmiotu podaje<br />

jego nazwę i ilość osób, które zdały egzamin z tego przedmiotu.<br />

Zadanie 6. Utwórz w SQL zapytanie, które znajduje nazwiska wszystkich<br />

studentów, którzy nie otrzymali z żadnego egzaminu oceny > 4. Zadanie<br />

rozwiąż na dwa sposoby (<strong>złączenia</strong> i <strong>podzapytania</strong>).<br />

Zadanie 7. Utwórz w SQL kod podwyższający o 100 zł. kwotę stypendium<br />

studentom z <strong>Wydział</strong>u <strong>Matematyki</strong> i Informatyki (np. wydzial=WMiI) z<br />

wyjątkiem studentów I roku.<br />

Zadanie 8. Utwórz w SQL tabelę (bez klucza głównego):<br />

Stypendia(nr_indeks, rok_stud, kwota_styp).<br />

Napisz w SQL fragment kodu podwyższający o 20% kwote_styp wszystkim<br />

studentom z wyjątkiem studentów I roku.<br />

Zadanie 9. Zmodyfikuj definicję powyższej tabeli Stypendia, określając klucz<br />

główny nr_indeks. Użyj „ALTER TABLE”.<br />

Zadanie 10. Usuń kolumnę rok_stud z tabeli Stypendia. Następnie dodaj<br />

kolumnę rok_stud do tabeli Studenci.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!