FÖ 9: Databaskursen 1. SQL 2. Utsökningar mot flera tabeller 3. Nästlad sökning eller sub queries 4. IN-operatorn 5. Join 6. Kartesisk produkt 7. Tabellalias 8. Distincti 9. Group by 10. Having 11. In Line View 12. Order by 13. Pseudokolumnen: rownum 1 Pär Douhan, pdo@du.se
Övningsuppgifter ift STUDENT # studnr * fnamn * enamn o regdatum TENTA KURS # radnr # kursnr (#) studnr * kursnamn (#) kursnr * nivå * tentadatum * ämne * betyg * poäng Om du skriver ut filen: Fö 09 - Databas (SQL 2, utsökningar mot flera tabeller) Övning.docx så blir det lättare att hänga med! 2
Innehåll i övningstabellen kurs KURSNR KURSNAMN NIVÅ ÄMNE POÄNG ------ ----------------------- ---- ------------- ----- 1 beginning java A informatik 5 2 java with oracle B informatik 5 3 AI for masters D datateknik 5 4 software architecture C informatik 5 5 ångesthantering A psykologi 10 6 den sociala människan A sociologi 20 student STUDNR FNAMN ENAMN REGDATUM ------ ----------- -------------- ---------- 1 niklas strömberg 2002-08-28 2 arman dobitnik 2002-08-28 3 anna larsson 2001-08-28 4 lena nordin 2003-09-12 09 5 jörgen killing 2000-08-19 6 hans dalros 2005-09-01 tenta RADNR STUDNR KURSNR TENTADATUM BETYG ----- ------ ------ ---------- ----- 1 1 1 2002-10-23 3 2 1 2 2003-10-23 4 3 2 1 2002-10-23 5 4 2 2 2003-10-23 23 5 5 2 6 2003-01-23 VG 6 3 3 2003-01-23 4 7 4 3 2004-01-23 3 8 5 4 2001-10-25 G 3
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" d.v.s. visas utan dubbletter. Inga sorteringar (order by) i nästlade satser. 4
Join Kolumner från en eller fler tabeller kan visas. Resultatet visas med dubletter, måste "distinctas". 5
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 ENAMN ------ ------------------------- --------- 1 niklas strömberg 2 arman dobitnik 6
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 ENAMN ------ ------------------------- --------- 1 niklas strömberg 2 arman dobitnik 7
E3 E3: Gör samma sak som i E2 men använd Equi-Join i utan tabellalias. li select student.studnr,student.fnamn,student.enamn from student,tenta,kurs where lower(kurs.kursnamn) = 'beginning java' and student.studnr studnr = tenta.studnr and tenta.kursnr = kurs.kursnr; -- Join villkor Utelämnas join-villkor, så får vi kartesisk produkt! STUDNR FNAMN ENAMN ------ ------------------------- --------- 1 niklas strömberg 2 arman dobitnik 8
Kartesisk produkt En mängd är en oordnad d uppsättning unika data En databastabell är en mängd. Mängd A Mängd B Den kartesiska produkten A x B är mängden av alla par (a, b) B X 5 2 E 8 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)} 9
E4 E4: Gör samma som i E3 men använd tabellalias. li select s.studnr,s.fnamn,s.enamn from student s,tenta t,kurs k where lower(k.kursnamn) = 'beginning java' and s.studnr studnr = t.studnr and t.kursnr = k.kursnr; funkar inte med as STUDNR FNAMN ENAMN ------ ------------------------- --------- 1 niklas strömberg 2 arman dobitnik 10
E5 E5: Visa fnamn, enamn för de studenter t 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 11
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 where s.studnr = t.studnr order by enamn desc; -- Join villkor FNAMN ENAMN ------------------------- --------- niklas strömberg niklas strömberg lena nordin anna larsson jörgen killing arman dobitnik arman dobitnik arman dobitnik 12
E7 E7: Samma som E6, men utan dubbletter. select distinct t s.fnamn,s.enamn from student s,tenta t where s.studnr = t.studnr order by enamn desc; FNAMN ENAMN ------------------------- --------- niklas strömberg lena nordin anna larsson jörgen killing arman dobitnik 13
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 ENAMN ------------------------- --------- niklas strömberg lena nordin anna larsson jörgen killing arman dobitnik 14
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 15
E10 E10: Visa studnr, fnamn, enamn,antalantal kurser som studenterna har läst. select s.studnr,s.fnamn,s.enamn,count(t.radnr) antal_kurser from student s,tenta t where s.studnr = t.studnr group by s.studnr,s.fnamn,s.enamn; -- de kolumner som inte count jobbar med! STUDNR FNAMN ENAMN ANTAL_ KURSER ------ --------------- ---------------- ------------ 1 niklas strömberg 2 2 arman dobitnik 3 3 anna larsson 1 4 lena nordin 1 5 jörgen killing 1 16
E11 E11: Samma som i E10, men visa även de studenter som läst noll kurser. 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 where s.studnr = t.studnr(+) group by s.studnr,s.fnamn,s.enamn; STUDNR FNAMN ENAMN 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 17
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 where e s.studnr = t.studnr and t.kursnr = k.kursnr group by s.studnr,s.fnamn,s.enamn; STUDNR FNAMN ENAMN 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 18
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 where s.studnr = t.studnr and t.kursnr = k.kursnr group by s.studnr,s.fnamn,s.enamn order by sum(k.poäng) desc; STUDNR FNAMN ENAMN 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 19
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 where s.studnr = t.studnr 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 ENAMN SUMMA_POÄNG ------ --------------- ----------------- ----------- 2 arman dobitnik 30 1 niklas strömberg 10 20
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 where s.studnr = t.studnr 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 ENAMN SUMMA_POÄNG ------ --------------- ----------------- ----------- 2 arman dobitnik 30 21
The End 22