Databaser och Informationssystem 15 hp IK1008 Föreläsning 8 SQL, utsökningar mot flera tabeller Övningsuppgifter STUDENT TENTA KURS # studnr * fnamn * enamn o regdatum # radnr (#) studnr (#) kursnr * tentadatum * betyg # kursnr * kursnamn * nivå * ämne * poäng Om du skriver ut filen FÖ8_SQL_tabelldata.doc, så blir det lättare att följa med. 1
Nästlad sökning När kolumner skall visas från bara en tabell. IN-operatorn används när den nästlade SQL-satsen kan returnera fler än en rad. Den nästlade satsen måste vara inom (parentes). De nästlade satserna exekveras, i en viss given ordning, inifrån och ut. Resultatet "distinctas" dvs visas utan dubletter. Inga sorteringar (order by) i nästlade satser. Join Kolumner från en eller fler tabeller kan visas. Resultatet visas med dubletter, måste "distinctas". 2
E1 E1: Visa studnr,fnamn,enamn på de studenter som läst kurs nr 1 använd nästlad sökning. select studnr,fnamn,enamn from student where studnr in(select studnr from tenta where kursnr = 1); exekveras först 1 2 STUDNR FNAMN ------ ------------------------- --------- 1 niklas strömberg 2 arman dobitnik E2 E2: Visa studnr,fnamn,enamn på de studenter som läst en kurs med namnet 'beginning java'. Använd nästlad sökning. select studnr,fnamn,enamn from student where studnr in(select studnr from tenta 1 where kursnr in (select kursnr from kurs where lower(kursnamn) = 'beginning java')); 1 2 STUDNR FNAMN ------ ------------------------- --------- 1 niklas strömberg 2 arman dobitnik 3
E3 E3: Gör samma sak som i E2 men använd Equi-Join utan tabellalias. select student.studnr,student.fnamn,student.enamn from student,tenta,kurs where lower(kurs.kursnamn) = 'beginning java' and student.studnr = tenta.studnr and tenta.kursnr = kurs.kursnr; -- Join villkor Utelämnas join-villkor, så får vi kartesisk produkt STUDNR FNAMN ------ ------------------------- --------- 1 niklas strömberg 2 arman dobitnik Kartesisk produkt En mängd är en oordnad uppsättning unika data En databastabell = en mängd. Mängd A Mängd B Den kartesiska produkten A x B är mängden av alla par (a,b) B E X 5 2 8 Glöm inte joinvillkoret! oet A x B = {B,X,E} x {5,2,8} = {(B,5),(B,2),(B,8),(X,5),(X,2),(X,8),(E,5),(E,2),(E,8)} 4
E4 E4: Gör samma som i E3 men använd tabellalias. select s.studnr,s.fnamn,s.enamn from student s,tenta t,kurs k where lower(k.kursnamn) = 'beginning java' and s.studnr = t.studnr and t.kursnr = k.kursnr; funkar inte med as STUDNR FNAMN ------ ------------------------- --------- 1 niklas strömberg 2 arman dobitnik E5 E5: Visa fnamn, enamn för de studenter som inte läst någon kurs. select initcap(fnamn ' ' enamn) "Har inte läst någon kurs:" from student where studnr not in (select studnr from tenta); Har inte läst någon kurs: ------------------------- Hans Dalros 5
E6 E6: Visa fnamn,enamn på de studenter som läst någon kurs, sortera fallande på enamn. Använd join. select s.fnamn,s.enamn from student s,tenta t order by enamn desc; -- Join villkor FNAMN ------------------------- --------- niklas strömberg niklas strömberg lena nordin anna larsson jörgen killing arman dobitnik arman dobitnik arman dobitnik E7 E7: Samma som E6, men UTAN dubletter. select distinct s.fnamn,s.enamn from student s,tenta t order by enamn desc; FNAMN ------------------------- --------- niklas strömberg lena nordin anna larsson jörgen killing arman dobitnik 6
E8 E8: Samma som E7, men använd nästlad sökning. select fnamn,enamn from student where studnr in (select studnr from tenta) order by enamn desc; -- ingen sortering i den nästlade satsen! FNAMN ------------------------- --------- niklas strömberg lena nordin anna larsson jörgen killing arman dobitnik E9 E9: Visa studnr för de studenter som INTE läst kursen 'AI for masters'. Join eller nästlad sökning? Nästling, med negationen i den yttre satsen. select studnr from student where studnr not in (select studnr from tenta where kursnr in (select kursnr from kurs where upper(kursnamn) = 'AI FOR MASTERS')); STUDNR ------ 1 2 5 6 7
E10 E10: Visa studnr,fnamn,enamn,antal kurser som studenterna har läst. select s.studnr,s.fnamn,s.enamn,count(t.radnr) antal_kurser from student s,tenta t group by s.studnr,s.fnamn,s.enamn; -- de kolumner som inte count jobbar med! STUDNR FNAMN ANTAL_KURSER ------ --------------- ---------------- ------------ 1 niklas strömberg 2 2 arman dobitnik 3 3 anna larsson 1 4 lena nordin 1 5 jörgen killing 1 E11 E11: Samma som i E10, men visa även de studenter som läst noll kurser(överkurs). Outer Join visar NULL-värden. select s.studnr,s.fnamn,s.enamn,nvl(count(t.radnr),0) antal_kurser from student s,tenta t (+) group by s.studnr,s.fnamn,s.enamn; STUDNR FNAMN ANTAL_KURSER ------ -------------------------------------------- 1 niklas strömberg 2 2 arman dobitnik 3 3 anna larsson 1 4 lena nordin 1 5 jörgen killing 1 6 hans dalros 0 8
E12 E12: Visa studnr,fnamn,enamn,antal poäng som varje student har läst. select s.studnr,s.fnamn,s.enamn,sum(k.poäng) summa_poäng from student s,tenta t,kurs k and t.kursnr = k.kursnr group by s.studnr,s.fnamn,s.enamn; STUDNR FNAMN SUMMA_POÄNG ------ --------------- --------------- ----------- 1 niklas strömberg 10 2 arman dobitnik 30 3 anna larsson 5 4 lena nordin 5 5 jörgen killing 5 E13 E13: Samma som E12, men sortera så att den med mest poäng kommer överst. select s.studnr,s.fnamn,s.enamn,sum(k.poäng) summa_poäng from student s,tenta t,kurs k and t.kursnr = k.kursnr group by s.studnr,s.fnamn,s.enamn order by sum(k.poäng) desc; STUDNR FNAMN SUMMA_POÄNG ------ --------------- --------------- ----------- 2 arman dobitnik 30 1 niklas strömberg 10 3 anna larsson 5 4 lena nordin 5 5 jörgen killing 5 9
E14 E14: Samma som E13, men visa bara de som har 10 poäng eller mer. select s.studnr,s.fnamn,s.enamn,sum(k.poäng) summa_poäng from student s,tenta t,kurs k and t.kursnr = k.kursnr group by s.studnr,s.fnamn,s.enamn having sum(k.poäng) >= 10 -- villkor för gruppfunktioner order by sum(k.poäng) desc; STUDNR FNAMN SUMMA_POÄNG ------ --------------- ----------------- ----------- 2 arman dobitnik 30 1 niklas strömberg 10 E15 E15: Samma som E14, men visa bara den översta posten. Använd så kallad 'in line view' för att lösa uppgiften: select * from ( -- in line view börjar select s.studnr,s.fnamn,s.enamn,sum(k.poäng) summa_poäng from student s,tenta t,kurs k and t.kursnr = k.kursnr group by s.studnr,s.fnamn,s.enamn having sum(k.poäng) >= 10 order by sum(k.poäng) desc ) -- in line view slutar where rownum = 1; -- använder pseudokolumnen rownum STUDNR FNAMN SUMMA_POÄNG ------ --------------- ----------------- ----------- 2 arman dobitnik 30 Ω 10