Grupowanie, złączenia i podzapytania - Wydział Matematyki i ...
Grupowanie, złączenia i podzapytania - Wydział Matematyki i ... Grupowanie, złączenia i podzapytania - Wydział Matematyki i ...
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
- Page 2 and 3: AND film_id > 2 ORDER BY "ID filmu"
- Page 4 and 5: GROUP BY studio_id HAVING "liczba f
- Page 6 and 7: Złączenia i podzapytania Złącze
- Page 8 and 9: jest równoważne z SELECT tytul FR
- Page 10: Zadania Zadanie 1. Utwórz w SQL pe
<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.