Inleiding Databanken: oefeningen Sven Casteleyn Lokaal: 6G319 Email: Sven.Casteleyn@vub.ac.be HomePage: te bereiken via http://wise.vub.ac.be/
Groeperen van resultaten (1/2) (GROUP BY) GROUP BY wordt gebruikt voor het groeperen van resultaten Wanneer een GROUP BY wordt gebruikt, moet elk item in de SELECT clause een enkele waarde zijn per groep De SELECT clause mag enkel kolomnamen, aggregate functions, constanten en combinaties hiervan bevatten.
Groeperen van resultaten (2/2) (GROUP BY) Alle namen die in de SELECT lijst voorkomen moeten ook in de GROUP BY clause voorkomen, tenzij ze gebruikt worden in een aggregate function Als een WHERE clause gebruikt wordt, wordt die eerst toegepast, daarna wordt de GROUP BY toegepast
Groeperen van resultaten (GROUP BY): voorbeeld Geef het aantal studenten in elk studiejaar en geef ook de geboortedatum van de jongste student in elk studiejaar SELECT StudentGrade, COUNT(StudentSecondname) AS aantalstudenten, MAX(StudentDateOfBirth) FROM student GROUP BY StudentGrade ORDER BY StudentGrade
Groeperen van resultaten (GROUP BY): voorbeeld
GROUP BY: wat gebeurt er? SQL verdeelt eerst de studenten volgens hun StudentGrade Daarna gaat hij binnen deze groepen de studenten gaan tellen (COUNT operatie) en de jongste student zoeken (MAX operatie) Tenslotte wordt het resultaat stijgend gerangschikt volgens StudentGrade
Groepen beperken (HAVING) (1/2) HAVING wordt gebruikt in combinatie met GROUP BY, en dient om het aantal groepen te beperken Equivallent van de WHERE clause, die individuele rijen filtert; HAVING filtert groepen
Groepen beperken (HAVING) (2/2) Kolommen die voorkomen in de HAVING clause moeten ook voorkomen in de GROUP BY lijst, tenzij ze in een aggregate function voorkomen.
Groepen beperken (HAVING): voorbeeld SELECT StudentGrade, COUNT(StudentSecondname) AS aantalstudenten, MIN(StudentDateOfBirth) FROM student GROUP BY StudentGrade HAVING COUNT(StudentSecondname) > 10 ORDER BY StudentGrade
Queries over meerdere relaties Tot nu toe hebben we enkel gegevens opgehaald uit 1 enkele relatie Er zijn twee manieren om informatie uit verschillende relaties te combineren: door gebruik van cartesisch product (en in het bijzonder joins) door gebruik van subqueries
Queries over meerdere relaties: cartesisch product De meest triviale manier om informatie uit meerdere relaties te combineren is het cartesisch product Het cartesisch product van twee relaties bestaat eruit om alle mogelijke combinaties van tuples in het resultaat op te nemen
Queries over meerdere relaties: cartesisch product (voorbeeld) StudentID Classname 1 Databanken Kernfysica 2 AI StudentFirstName StudentSecondName StudentID Paul Maes 1 Dirk Palm 2 x
Queries over meerdere relaties: cartesisch product (voorbeeld) StudentID Classname 1 Databanken Kernfysica 2 AI StudentFirstName StudentSecondName StudentID Paul Maes 1 Dirk Palm 2 x
Queries over meerdere relaties: cartesisch product (voorbeeld) StudentID Classname 1 Databanken Kernfysica 2 AI StudentFirstName StudentSecondName StudentID Paul Maes 1 Dirk Palm 2 x
Queries over meerdere relaties: cartesisch product (voorbeeld) StudentID Classname 1 Databanken Kernfysica 2 AI StudentFirstName StudentSecondName StudentID Paul Maes 1 Dirk Palm 2 x = StudentFirstName StudentSecondName StudentID Classname Paul Maes 1 Databanken Kernfysica 2 AI Dirk Palm
Queries over meerdere relaties: join (1/3) StudentID Classname 1 Databanken Kernfysica 2 AI StudentFirstName StudentSecondName StudentID Paul Maes 1 Dirk Palm 2 I.p.v. alle mogelijke combinaties is de volgende vraag misschien nuttiger: “Geef voor alle studenten naam, voornaam, studentennummer, en de vakken die ze volgen”
Queries over meerdere relaties: join (2/3) Dit komt erop neer een cartesisch product te nemen, en daarbij te zorgen dat enkel de juiste tupels overblijven (nl. het juiste vak(ken) bij de juiste student) StudentFirstName StudentSecondName StudentID Classname Paul Maes 1 Databanken Kernfysica 2 AI Dirk Palm
Queries over meerdere relaties: join (3/3) SELECT Student.StudentSecondname, Student.StudentFirstname, Enrollment.StudentID, Enrollment.Classname FROM Student, Enrollment WHERE Student.StudentID = Enrollment.StudentID Join conditie StudentFirstName StudentSecondName StudentID Classname Paul Maes 1 Databanken Kernfysica 2 AI Dirk Palm
Queries over meerdere relaties: join (opmerkingen) De join conditie bestaat eruit dat we een candidate key uit 1 relatie gelijk stellen aan de corresponderende foreign key uit de andere relatie Op deze manier kunnen uiteraard ook meer dan 2 relaties gecombineerd worden
Queries over meerdere relaties: join (samengevat) Vorm het Cartesisch product van de relaties uit de FROM clause Filter de rijen uit het resultaat die niet aan de (join-) conditie voldoen uit de WHERE clause voldoen Voor de overblijvende rijen, vind de waarde voor elk item in de SELECT clause SELECT DISTINCT -> elimineer dubbels ORDER BY -> sorteer de resultaats-tabel
Queries over meerdere relaties: Gebruik van aliasen Een alias kan gebruikt worden op tabellen een handiger naam te geven binnen een query. De alias mag in de query gebruikt worden als was het de tabelnaam Aliasen verschijnen in de FROM clause SELECT s.StudentSecondname, s.StudentFirstname, e.StudentID, e.Classname FROM Student s, Enrollment e WHERE s.StudentID = e.StudentID
Queries over meerdere relaties: Sorteren van een join Geef een lijst terug van voornaam, naam en ingeschreven vak, gerangschikt volgens studiejaar (laagste jaar eerst) en binnen elk jaar alfabetisch gerangschikt op naam
Queries over meerdere relaties: Sorteren van een join SELECT StudentSecondname, StudentFirstname, Enrollment.Classname FROM Student, Enrollment WHERE Student.StudentID = Enrollment.StudentID ORDER BY StudentGrade, StudentSecondName
Queries met meerdere relaties: meervoudig groeperen Geef het aantal studenten terug per studiejaar per vak SELECT s.StudentGrade, e.Classname, count(*) AS Count FROM Student s, Enrollment e WHERE s.StudentID = e.StudentID GROUP BY s.StudentGrade, e.Classname ORDER BY s.StudentGrade, e.Classname
Queries over meerdere relaties: Nested subqueries (revisited) Probleem: geef per vak dat gegeven wordt de naam van de oudste student terug die dat vak volgt De vraagstelling lijkt een GROUP BY oplossing te suggereren: select classname, min(studentdateofbirth) from student s, enrollement e where e.studentid = s.studentid GROUP BY classname Maar, hoe ook de naam teruggeven??
Queries over meerdere relaties: Nested subqueries (revisited) SELECT e1.classname , s1.studentfirstname, s1.studentsecondname FROM student s1, enrollment e1 WHERE s1.studentid = e1.studentid AND s1.studentdateofbirth = (SELECT min(studentdateofbirth) FROM student s2, enrollment e2 WHERE s2.studentid = e2.studentid AND e1.classname = e2.classname )
Queries over meerdere relaties: Nested subqueries (revisited) SELECT e1.classname , s1.studentfirstname, s1.studentsecondname FROM student s1, enrollment e1 WHERE s1.studentid = e1.studentid AND s1.studentdateofbirth = (SELECT min(studentdateofbirth) FROM student s2, enrollment e2 WHERE s2.studentid = e2.studentid AND e1.classname = e2.classname )
Queries over meerdere relaties: Nested subqueries (revisited) SELECT e1.classname , s1.studentfirstname, s1.studentsecondname FROM student s1, enrollment e1 WHERE s1.studentid = e1.studentid AND s1.studentdateofbirth = (SELECT min(studentdateofbirth) FROM student s2, enrollment e2 WHERE s2.studentid = e2.studentid AND e1.classname = e2.classname )
Queries over meerdere relaties: Nested subqueries (revisited) SELECT e1.classname , s1.studentfirstname, s1.studentsecondname FROM student s1, enrollment e1 WHERE s1.studentid = e1.studentid AND s1.studentdateofbirth = (SELECT min(studentdateofbirth) FROM student s2, enrollment e2 WHERE s2.studentid = e2.studentid AND e1.classname = e2.classname )
Queries over meerdere relaties: Nested subqueries (revisited) SELECT e1.classname , s1.studentfirstname, s1.studentsecondname FROM student s1, enrollment e1 WHERE s1.studentid = e1.studentid AND s1.studentdateofbirth = (SELECT min(studentdateofbirth) FROM student s2, enrollment e2 WHERE s2.studentid = e2.studentid AND e1.classname = e2.classname )