ANALYSE 3 INFANL01-3 WEEK 6 CMI Informatica
ANALYSE 3- INFANL01-3 ▸ Vorige les ▸ Subqueries met correlaties ▸ Subqueries zonder correlaties ▸ Views ▸ Transacties
VORIGE LES
4 GROUP BY GROUP BY kolommen groepeert rijen met dezelfde waarden in alle gespecificeerde kolommen bijv.: SELECT spelersnr, bedrag, count(bedrag) FROM boetes GROUP BY spelersnr, bedrag
GROUP BY op 1 kolom FROM BOETESGROUP BY SPELERSNR 1 GROEP PER SPELERSNR
GROUP BY(1) FROM BOETES GROUP BY SPELERSNR, BEDRAG 1 GROEP PER SPELERSNR-BEDRAG COMBINATIE
GROUP BY (2) SELECT SPELERSNR, BEDRAG, COUNT(BEDRAG)
Joins Joins: INNER JOIN, OUTER JOIN, LEFT, RIGHT, FULL, CROSS..... EQUI-JOIN, NON-EQUI-JOIN, THETA JOIN.... Cartesisch product
JOINs inner joins Wat is een INNER JOIN? in een INNER JOIN vind je alleen rijen terug waarvan het gemeenschappelijke attribuut in beide tabellen voorkomt; (bijv. bij spelers en boetes, de doorsnede van de verzamelingen spelersnr)
JOINs outer joins (1) Vraag: Wat als je ook spelers zonder boetes in het eindresultaat wilt zien? ???
JOINs outer joins (2) Vraag: Wat als je ook spelers zonder boetes in het eindresultaat wilt zien? Antwoorden: SELECT naam, spelersnr, bedrag FROM spelers LEFT OUTER JOIN boetes USING (spelersnr); SELECT naam, spelers.spelersnr, bedrag FROM spelers LEFT OUTER JOIN boetes ON (spelers.spelersnr=boetes.spelersnr); LEFT OUTER JOIN zorgt er voor dat ALLE rijen uit de linker tabel voorkomen in resultaat
JOINs outer joins (4) Ook boetes zonder spelers (mag niet voorkomen bij goed gedefinieerde ref integrity): SELECT naam, spelersnr, bedrag FROM spelers RIGHT OUTER JOIN boetes USING (spelersnr); Ook spelers zonder boete èn boetes zonder speler: SELECT naam, spelersnr, bedrag FROM spelers FULL OUTER JOIN boetes USING (spelersnr);
JOINs equi-joins, theta-joins EQUI-JOIN gebruikt de = operator in de join-conditie: SELECT naam, spelersnr, bedrag FROM spelers, boetes WHERE spelers.spelersnr = boetes.spelersnr; NON-EQUI-JOIN gebruikt een andere operator: greater-than join: speler.rating > tegenstander.rating not-equal-to join: s1.spelersnr <> s2.spelersnr THETA-JOIN is de algemene term voor willekeurige vergelijkingsoperator (omvat dus equi- en non-equi joins)
SUBQUERIES
Subqueries Inleiding Single-row Muliple-row (vs JOINs) Correlated
Subqueries Wanneer te gebruiken: Een subquery wordt gebruikt als je weet hoe om te zoeken naar een waarde met behulp van een SELECT statement maar weet niet de exacte waarde in de database. Subqueries kunnen een alternatieve manier zijn voor JOINs om waarden uit meerdere tabellen te krijgen. Je kan maar één ORDER BY gebruiken voor de hele statement
Subqueries (single-row) Single-row subqueries zijn gebaseerd op vergelijkingsoperatoren (>, =,> =,, <=) De subquery zelf levert slechts een rij terug aan de outer-query Als de subquery een NULL geeft dan is het resultaat van de hele query NULL
Subqueries (single-row)
Subqueries (multiple-row) Multiple-row subqueries zijn gebaseerd op de vergelijkingsoperatoren (IN, ANY, EXISTS, ALL) Het resultaat van de subquery is meer dan een rij Afhankelijk van de operator zijn er verschillende resultaten bij NULL IN, ANY en EXISTS leveren wel rijen op ALL levert NULL op
SELECT … FROM … WHERE IN (1) IN : WHERE IN IN wordt gebruikt in WHERE (rij-voorwaarde) om de rijen te selecteren met een attribuut-waarde die voorkomt in de verzameling attribuut waarden. kan een letterlijk lijstje zijn (1,2,3) of het resultaat van een SELECT SELECT * FROM spelers WHERE spelersnr IN (1,2,3); SELECT naam AS aanvoerder FROM spelers WHERE spelersnr IN (SELECT spelersnr FROM teams);
IN (2) IN met subquery vs. join SELECT naam AS aanvoerder FROM spelers WHERE spelersnr IN (SELECT spelersnr FROM teams); Alternatief voor subquery: SELECT naam AS aanvoerder FROM spelers, teams WHERE spelers.spelersnr = teams.spelersnr;
IN (3) IN met subquery vs. Join : opgave 1 Opgave 1: Geef spelersnr en naam van alle spelers die minstens één wedstrijd voor team 1 hebben gespeeld. Geef zowel de oplossing met subquery als die met join. spelers(spelersnr, naam,...) Teams(teamnr,spelersnr, divisie) wedstrijden(wedstrijdnr, teamnr, spelersnr, gewonnen, verloren)
IN (4) IN met subquery vs. join : antwoord 1 Opgave 1: geef spelersnr en naam van alle spelers die minstens één wedstrijd voor team 1 hebben gespeeld. Geef zowel de oplossing met subquery als met join Antwoord 1: SELECT spelersnr, naam FROM spelers WHERE spelersnr IN ( SELECT spelersnr FROM wedstrijden WHERE teamnr=1 ); SELECT spelersnr, naam FROM spelers, wedstrijden WHERE spelers.spelersnr=wedstrijden.spelersnr AND wedstrijden.teamnr=1;
IN (4) IN met subquery vs. join : antwoord 1 Opgave 1: geef spelersnr en naam van alle spelers die minstens één wedstrijd voor team 1 hebben gespeeld. Geef zowel de oplossing met subquery als met join Antwoord 1: SELECT spelersnr, naam FROM spelers, wedstrijden WHERE spelers.spelersnr=wedstrijden.spelersnr AND wedstrijden.teamnr=1;
IN (5) IN met subquery vs. Join : opgave 2 Opgave 2: Geef spelersnr en naam van alle spelers die minstens één wedstrijd hebben gespeeld in teams die niet door speler 6 werden aangevoerd
IN (6) IN met subquery vs. Join : antwoord 2 Opgave 2: Geef spelersnr en naam van alle spelers die minstens één wedstrijd hebben gespeeld in teams die niet door speler 6 werden aangevoerd Antwoord 2: SELECT spelersnr, naam FROM spelers WHERE spelersnr IN ( SELECT spelersnr FROM wedstrijden WHERE teamnr NOT IN ( SELECT teamnr FROM teams WHERE spelersnr=6 ) );
IN (6) IN met subquery vs. Join : antwoord 2 Opgave 2: Geef spelersnr en naam van alle spelers die minstens één wedstrijd hebben gespeeld in teams die niet door speler 6 werden aangevoerd Antwoord 2: SELECT spelersnr, naam FROM spelers,wedstrijden,teams WHERE spelers.spelersnr=wedstrijden.spelersnr AND wedstrijden.teamnr=teams.teamnr AND NOT teams.spelersnr = 6;
SELECT … FROM … WHERE EXISTS EXISTS wordt gebruikt in WHERE (rij-voorwaarde) om die rijen te selecteren die voorkomen in de verzameling die het resultaat is van de gecorreleerde subquery SELECT naam AS aanvoerder FROM spelers WHERE EXISTS ( SELECT * FROM teams WHERE spelersnr = spelers.spelersnr ); voor elke rij uit de spelers tabel wordt de subquery opnieuw uitgevoerd. het resultaat van de subquery kan dan ook verschillen voor elke rij uit de spelerstabel. ALTERNATIEF?
SELECT … FROM … WHERE EXISTS Alternatief: SELECT naam AS aanvoerder FROM spelers, teams WHERE spelers.spelersnr=teams.spelersnr;
SELECT … FROM … WHERE ALL (1) SELECT spelersnr, naam, geb_datum FROM spelers WHERE geb_datum <= ALL (SELECT geb_datum FROM spelers); voor elke speler wordt geb_datum vergeleken met alle andere geb_data; de speler wordt alleen opgenomen in het eindresultaat als zijn/haar geb_datum <= aan alle andere geb_data; (maw de kleinste is van alle geb_data) Alternatief: SELECT spelersnr, naam, geb_datum FROM spelers WHERE geb_datum <= (SELECT MIN(geb_datum) FROM spelers);
ALL (2) Opgave 1 Opgave 1: Geef het alternatief zonder subquery van: SELECT spelersnr, naam, geb_datum FROM spelers WHERE geb_datum <= (SELECT MIN( geb_datum ) FROM spelers);
ALL (2) Antwoord 1 Opgave 1: Geef het alternatief zonder subquery van: SELECT spelersnr, naam, geb_datum FROM spelers WHERE geb_datum <= ALL (SELECT geb_datum FROM spelers); Antwoord 1: SELECT p.spelersnr, p.naam, p.geb_datum FROM spelers AS p, spelers as q GROUP BY p.spelersnr, p.naam, p.geb_datum HAVING p.geb_datum <= MIN( q.geb_datum );
SELECT … FROM … WHERE ANY (1) SELECT spelersnr, naam, geb_datum FROM spelers WHERE NOT geb_datum > ANY ( SELECT geb_datum FROM spelers ); voor elke speler wordt geb_datum vergeleken met alle andere geb_data; de huidige speler wordt niet (NOT) opgenomen in het eindresultaat als er één of meer (ANY) speler ouder is; Alternatief (makkelijker): SELECT spelersnr, naam, geb_datum FROM spelers WHERE NOT geb_datum > (SELECT MIN(geb_datum) FROM spelers);
ANY (2) Alternatief zonder subquery: SELECT p.spelersnr, p.naam, p.geb_datum FROM spelers AS p, spelers as q GROUP BY p.spelersnr,p.naam,p.geb_datum HAVING NOT p.geb_datum > MIN(q.geb_datum);
Conclusie (1) IN, EXISTS, ALL, ANY Er zijn veel wegen die naar Rome leiden verschillende SQL queries -> zelfde resultaat Een SQL statement met subquery kan altijd worden vervangen door een alternatief met join. In SQL queries met joins (en zonder subqueries; mySQL!) heb je GROUP BY en HAVING nodig in vergelijkingen met resultaten van set-functies (MIN,MAX,etc) Gebruik het meest leesbare SQL statement !
Conclusie (2) IN, EXISTS, ALL, ANY Gebruik het meest leesbare SQL statement : Liever: SELECT naam FROM spelers WHERE geb_datum = ( SELECT MIN(geb_datum) FROM spelers ); Dan: constructies met ANY of ALL
Conclusie (2) IN, EXISTS, ALL, ANY Gebruik het meest leesbare SQL statement : En liever: SELECT naam AS aanvoerder FROM spelers WHERE spelersnr IN ( SELECT spelersnr FROM teams ); of (zonder subquery): SELECT naam AS aanvoerder FROM spelers, teams WHERE spelers.spelersnr=teams.spelersnr; Dan: een constructie met EXISTS
Subqueries (correlated) Correlated subquery is een subquery die waarden gebruikt van de outer-query. De subquery wordt eenmaal geëvalueerd voor elk rij van de outer-query.
VIEWS
VIEWs Wat is een VIEW? een view is een ‘virtuele’ tabel, die is gebaseerd op ‘echte’ basistabellen (dwz tabellen die gegevens bevatten) Waarom VIEWs? VIEWs kunnen worden gebruikt om gegevens uit verschillende tabellen te halen. Gebruikers kunnen dezelfde data op verschillende manieren zien. VIEWs bieden groepen gebruikers toegang tot gegevens op basis van hun permissies of criteria
Hoe definieer je een VIEW? (formeel) ::= CREATE VIEW [ ] AS [WITH CHECK OPTION] ::= | | ( )
Hoe definieer je een VIEW? (voorbeelden) CREATE VIEW wedstrijdspelers AS SELECT * FROM spelers WHERE bondsnr IS NOT NULL; CREATE VIEW aanvoerders AS SELECT naam, teamnr,divisie FROM spelers,teams WHERE spelers.spelersnr=teams.spelersnr;
VIEWs VIEWs zijn altijd actueel wijzigingen in onderliggende tabellen zijn direct in een VIEW terug te zien Sommige VIEWs zijn wijzigbaar. Dat wil zeggen, je kunt ze gebruiken in queries als UPDATE, DELETE Voorwaarde: er moet een één-op-één relatie tussen de rijen in het VIEW en de rijen in de onderliggende tabel. Heeft een view een één-op-één relatie als deze constructies gebruikt? Aggregate functions (SUM(), MIN(), MAX(), COUNT(), enz.) DISTINCT GROUP BY HAVING Enz.
TRANSACTIES
Transactie ▸ Een transactie bestaat uit een aantal samenhangende wijzigingen in een database, waarbij ervoor gezorgd wordt dat deze wijzigingen ofwel allemaal plaatsvinden, ofwel geen van alle. ▸ Een transactie bestaat uit de volgende instructies: ▸ START TRANSACTION: Begint een transactie ▸ COMMIT: representeert de tijdspunt waar de het resultaat van de transactie opgeslagen kan worden en het eind van de transactie ▸ ROLLBACK: verwijdert alle verandering aan de data tot een bepaalde tijdspunt of tot het begin van de transactie ▸ SAVEPOINT: een markeringstijdspunt binnen de transactie
Eigenschappen van RDBMS en transacties Atomicity Consistency Isolation Durability Genaamd ACID
Transacties in MySQL ▸ Implementatie van transacties verschilt per SQL dialect ▸ MySQL MyISAM engine ondersteunt het niet (sinds v5.5 is InnoDB default engine) ▸ InnoDB ondersteunt transacties
Voorbeeld Welke data worden opgeslagen in de tabel myTable na deze transaction? 1. START TRANSACTION; 2. INSERT INTO myTable(col1, col2) VALUES(10, 10); 3. SAVEPOINT my_savepoint_1; 4. INSERT INTO myTable(col1, col2) VALUES(20, 20); 5. SAVEPOINT my_savepoint_2; 6. INSERT INTO myTable(col1, col2) VALUES(30, 30); 7. ROLLBACK TO SAVEPOINT my_savepoint_1; 8. INSERT INTO myTable(col1, col2) VALUES(40, 40); 9. COMMIT;