Puzzelen met SQL: Fileleed

Vergelijkbare documenten
Puzzelen met SQL DEV. Crash SQL Investigation

Puzzelen met SQL 38. De Muzieklijst, deel 2 PUZZELEN MET SQL

Databank - Basis 1. Inhoud. Computervaardigheden en Programmatie. Hoofdstuk 4 Databank - Basis. Terminologie. Navigeren door een Venster

[TOETS SQL INLEIDING]

Inhoud. Voorwoord Belangrijkste kenmerken van dit boek De opzet van dit boek Over de auteur Woord van dank

SQL Aantekeningen 3. Maarten de Rijke 22 mei 2003

Puzzelen met SQL DBA. De muzieklijst, deel 1. De tabellen De tabellen die we gaan gebruiken in deze puzzel zijn weergegeven in afbeelding 1.

SQL is opgebouwd rond een basisinstructie waaraan één of meerdere componenten worden toegevoegd.

Inhoud. Voorwoord 1 Belangrijkste kenmerken van dit boek 1 De opzet van dit boek 1 Over de auteurs 2 Woord van dank 2

17. Scalaire functies

DBMS. DataBase Management System. Op dit moment gebruiken bijna alle DBMS'en het relationele model. Deze worden RDBMS'en genoemd.

Structured Query Language (SQL)

Introductie (relationele) databases

Computervaardigheden. Universiteit Antwerpen. Computervaardigheden en Programmatie. Grafieken en Rapporten 1. Inhoud. Anatomie van een databank

Structured Query Language

Elfde-Liniestraat Hasselt Schooljaar TINFO POKER GAME Oracle Scripts

Sparse columns in SQL server 2008

Modelleren in SQL DBA. De wondere wereld tussen GROUP BY en ORDER BY

Trainingsschema Alpe d HuZes 4 x per week

Les 2 Eenvoudige queries

Javascript oefenblad 1

DBMS SQL. Relationele databases. Sleutels. DataBase Management System. Inleiding relationele databases. bestaan uit tabellen.

ISO Query By Example

Query SQL Boekje. Fredrik Hamer

Oracle 11g R2 voor ontwikkelaars - deel 1

JANUARI Yogacollege Tilburg. Telefoon:

11. Het selecteren van gegevens deel II

Databases - Inleiding

MA!N Rapportages en Analyses

SQL manipulatietaal. We kunnen er data mee toevoegen, wijzigen en verwijderen uit een database.

Toon TITEL, JAAR en PLATVORM van GAMES die voor het jaar 2000 uitkwamen op Nintendo 64

Zelftest SQL Workshop

Les 11 : Basis SQL (deel2).

1. Inleiding Inleiding SQL Inleiding Database, databaseserver en databasetaal Het relationele model...

Data Warehouse Script Generator Doel

Pascal uitgediept Data structuren

Opdracht. Gezond bewegen? Doen!

SQL STATEMENTS. Deze kolom kan grote stukken tekst aan en is bedoeld om tekst erin de plaatsen. Geheel getal, bijvoorbeeld 8, 63, 835 NUMERIC

Datamodelleren en databases 2011

SQL: query taal met. woorden. ISO SQL: Structured Query Language. de SQL basis query structuur. voorbeeld: doel: intuitieve query taal

ISO SQL: Structured Query Language

SQL & Relationele datamodellen in interactieve media

8. De invoer van gegevens

Koppeling met een database

Boot - DEM/DT/BE_MFAO-BOO, Financieel Advies en Ondersteuning - DEM/DL/BE_TS-MFAO, Fiscaal - DEM/DT/BE_MFAO-FIS, Gespreksvaardigheden Gr.1...

Excel Controller. Handleiding Excel Controller Wizard

Puzzelen met SQL. Komkommertijd PUZZELEN MET SQL

Automatische Installatie op IIS server

SQL en XML. XML schema s & DMO. Entiteitsklasse en attribuut. SQL en XML. Datamodellering Schema een ruim begrip (zie Møller, p.

12. Meer dan één tabel gebruiken en sub-queries

DATAMODEL SQL. Middelbare School. Versie 1.0 Datum 30 oktober 2010 Auteur Mark Nuyens, studentnummer: Groep TDI 1

We moeten de accommodaties selecteren die 3 sterren hebben, en in land met ID 10 zitten.

Data Manipulatie. Query Talen. / Informatica

SQL: oefenen queries

Van CaseTalk naar een database in SQLite studio

Gekoppelde tabellen: de JOIN

Datakwaliteitsborging met Oracle dynamisch SQL

Zelftest DB2 for z/os basiscursus

Databases en SQL Foundation (DBSQLF.NL)

Zelftest SQL Workshop

UITZENDSCHEMA 2015 ZATERDAG :00 UUR TOT VRIJDAG :00 UUR

Inleiding Databases en Data Base Management Systems Tabellen Wat is SQL?... 5

1. Databanken. Wat is een databank? Verschillende opslagmethodes

Donderdag 28-jan 6:30 8:27 11:54 12:54 15:34 17:23 19:20

Les S-02: Meer geavanceerde SQL-instructies

Mijn eerste ADO.NET applicatie

Handleiding Reinder.NET.Tasks.SQL versie 2

Oracle Analytische Functies

Frequentieanalyse. Transporter: 5619 (15,30%) Vrachtwagen: 2311 (6,29%) Trailer: 43 (0,12%) Tweewieler: 1859 (5,06%) Auto: (73,24%)

Uurroosters administratie

Fun met webparts in ASP.Net

Les S-01: De basisbeginselen van SQL

De MySQL C API. Variabelen in C Functies in C Pointers in C

9 Meer over datatypen

Deel 1: Arduino kennismaking. Wat is een microcontroller, structuur van een programma, syntax,

Dataconversie met Oracle Spatial

Naam. Nummer:. Klas. Datum.

Excellerend Kwartaaltip

Slimhuishouden.nl. sslaap kamer. slaap kamer bad kamer trappen overloop. slaap kamer. slaap kamer. hal. zolder. woon kamer buiten boel.

SQL & Datamodelleren

Wat zijn de verschillen tussen SPSS 9 en SPSS 10?

SEMEX STUDIEREIS 2018 CANADA

Programmeren in Access met VBA

Databases SQL - meerdere tabellen

EXIN Databases en SQL Foundation

Programmeermethoden NA. Week 5: Functies (vervolg)

Programmeren in Access 2016 met VBA

ROUTEBESCHRIJVING H O W T O G E T H E R E

Hoofdstuk: 1 Principes van databases

Transcriptie:

Puzzelen met SQL: Fileleed Patrick Barel, Alex Nuijten - AMIS Services BV Na begin de dag met een dansje en de NOS Headlines worden op Radio 3 de files voorgelezen. Heleen de Geest of John Bakker, van de ANWB, geeft dan een klein overzicht van de files. Giel Beelen, s ochtends vroeg op de radio, vraagt altijd aan de ANWB er van de dag een voorspelling van de totale lengte van de files om half negen. Is het natte vinger-werk, of gebruiken ze een betere methode om tot een voorspelling te komen? In deze Puzzelen met SQL gaan we eens kijken of we een soortgelijke voorspelling kunnen doen. Over een uurtje 180 kilometer?. Voor deze puzzel gebruiken we twee tabellen. Eentje om de wegen vast te leggen - de naam van de weg en het traject op de weg. En een tabel om de daadwerkelijke file vast te leggen, de lengte van de file en op welke datum dit was. Laten we eerst maar eens simpel beginnen met de gegevens die we hebben, eerst maar de gemiddelde lengte per weg en dag. SQL> select w.naam 2, avg (f.lengte) gemiddelde_lengte 3, to_char (f.datum, 'Day', 'nls_date_language = dutch') DagVanDeWeek 4 from files f 5 join wegen w 6 on w.id = f.wegen_id 7 group by w.naam

8 9 ;, to_char (f.datum, 'Day', 'nls_date_language = dutch') NAAM GEMIDDELDE_ DAGVANDEW -------------------- ----------------- --------- 9 Zaterdag 12 Zondag 5.66666667 Maandag 9 Vrijdag A2 0 Dinsdag 6.33333333 Dinsdag 6 rows selected. Wat wellicht opvalt in het bovenstaande SQL statement is de derde parameter van de TO_CHAR functie. Het is reeds geruime tijd - zeker sinds Oracle 8.1.7. - mogelijk om een NLS parameter mee te geven om te specificeren in welke taal je de dag van de week wilt zien. Aangezien we in Nederland zijn willen we de dag van de week dan ook in het Nederlands zien: NLS_DATE_LANGUAGE = DUTCH. Deze zelfde parameter kun je ook opgeven bij de TO_DATE functie. Let echter wel op indien je de TO_CHAR in een WHERE clause gebruikt: SQL> select f.* 2 from files f 3 where to_char (f.datum, 'Day', 'nls_date_language = dutch') = 'Maandag' 4 / no rows selected No rows selected? Is dat niet vreemd? In het vorige SQL statement is toch duidelijk te zien dat we wel gegevens hebben voor een Maandag, maar toch word er voor dit statement geen rijen getoond. Dit heeft alles te maken met de TO_CHAR functie. TO_CHAR maakt van een NUMBER of DATE een CHAR, geen VARCHAR2. Een CHAR is per definitie een string met een vaste lengte. In het geval van de dagen van de week moet er voor gezorgd worden dat er voor dag met de langste naam voldoende ruimte is. Zoals je in onderstaande voorbeeld kan zien, wordt iedere dag van de week aangevuld met spaties: SQL> with rijen as 2 (select rownum rn 3 from dual 4 connect by level <= 7 5 ) 6 select '[' 7 to_char (sysdate + rn, 'Day', 'nls_date_language = dutch') 8 ']' dagen 9 from rijen 10 /

DAGEN ----------- [Woensdag ] [Donderdag] [Vrijdag ] [Zaterdag ] [Zondag ] [Maandag ] [Dinsdag ] 7 rows selected. In het Nederlands is Donderdag de dag met de langste naam, in het Engels is dat Wednesday: SQL> with rijen as 2 (select rownum rn 3 from dual 4 connect by level <= 7 5 ) 6 select '[' 7 to_char (sysdate + rn, 'Day', 'nls_date_language = english') 8 ']' dagen 9 from rijen 10 / DAGEN ----------- [Wednesday] [Thursday ] [Friday ] [Saturday ] [Sunday ] [Monday ] [Tuesday ] 7 rows selected. Dit is natuurlijk maar een kleinigheidje, maar soms zijn het deze kleinigheidjes waar veel tijd in gaat zitten. De gegevens die we van de files hebben zijn maar van een beperkt aantal dagen. Om een overzicht te krijgen van de gemiddelde file lengte per dag zullen we de dagen waar we geen gegevens van hebben erbij moeten verzinnen. Gebruik makend van Subquery Factoring (de WITH clause in onderstaand SQL statement) kunnen we de dagen van de week aan de Files tabel koppelen middels een OUTER JOIN. SQL> with dagen 2 as 3 (select to_char ( 4 trunc (sysdate, 'iw') - 1 + rownum

5, 'Day', 'nls_date_language = dutch') dag 6 from dual 7 connect by level <= 7) 8 select avg (f.lengte) 9, d.dag 10 from dagen d 11 left outer 12 join files f 13 on to_char (f.datum, 'Day', 'nls_date_language = dutch') = d.dag 14 group by d.dag 15 / AVG(F.) DAG ------------- --------- 5.66666667 Maandag 9 Zaterdag Woensdag 9 Vrijdag 4.75 Dinsdag Donderdag 12 Zondag 7 rows selected. Op regel 4 van bovenstaande code word het formaat masker IW gebruikt, wat voor ISO week nummer staat. Een ISO week begint altijd op maandag en eindigt altijd op zondag. In dit voorbeeld hadden we ook kunnen kiezen om het formaat masker WW te gebruiken, we zijn slechts geinteresseerd in de dagen van de week. Laten we eens gaan kijken of we een voorspelling kunnen gaan doen. Om het voorbeeld eenvoudig te houden beperken we ons tot de dinsdag. Waarom de dinsdag? Omdat we op deze dag gegevens hebben van twee verschillende wegen. Let op de spaties in regel 5 bij de voluitgeschreven dag van de week. 4 from files 6 / De voorspelling gaan we doen met behulp van de MODEL clause.de MODEL clause is

geintroduceerd in Oracle 10g en is erg krachtig. Niet alleen krachtig maar ook lastig in gebruik. Met de MODEL clause kun je vrijwel alles doen wat met Microsoft Excel ook kan, maar dan is het ingebakken in de SQL engine. Op basis van de resultaat set word in het geheugen een array opgebouwd die vervolgens gemanipuleerd kan worden. Even snel wat begrippen: Dimensions zijn vergelijkbaar met de aanduidingen die in Excel vergelijkbaar zijn met A3 of D5 ofwel de cellen. Hiermee kun je dus uniek een cel aanwijzen. De Dimension moet uniek zijn. Measures zijn vergelijkbaar met de cellen in Excel en deze waarden mogen dan ook gemanipuleerd worden. Alle manipulaties die je doet op de Measures worden niet in de database opgeslagen, maar worden alleen uitgevoerd op de resultaat set. De Rules bepalen de uiteindelijke manipulatie van de Measures. 4 from files 6 model 7 dimension by (wegen_id, datum) 8 measures (lengte) 9 rules () 10 / De MODEL clause begint met het keyword MODEL, gevolgd door DIMENSION BY, MEASURES en RULES. Al deze keywords moeten aanwezig zijn, anders krijg je compilatie fouten. Het echte werk doe je in de RULES, maar deze zijn optioneel. Als je ze weg laat krijg je dan ook niets bijzonders te zien, maar gewoon de resultaten die we al eerder zagen. Alleen de kolommen die genoemd worden in de DIMENSION BY en de MEASURES clause kunnen worden gebruikt in het SELECT deel van de query. Omdat de manipulatie van de resultaat set alleen maar op het scherm en niet in de database bestaat ook de mogelijkheid om extra rijen te laten genereren. In ons voorbeeld willen een extra rij genereren met de datum van volgende week dinsdag. Deze bewerking van de resultaat set definieer je dan ook in de Rules clause. En dat is heel eenvoudig, het is een kwestie van een dimension toevoegen van een datum die nog niet bestaat. Zou je echter Measures willen bewerken die wel in de resultaat set voorkomen, dan is het een kwestie van het opgeven van de bestaande dimension en daarvan de measure een nieuwe waarde toekennen.

4 from files 6 model 7 dimension by (wegen_id, datum) 8 measures (lengte) 9 rules ( 10 lengte [1, to_date ('05-10-2010 07:00', 'dd-mm-yyyy hh24:mi')] = -10 11 ) 12 / 1 05-OCT-10-10 Op regel 10 staat de rule die ervoor zorgt dat een extra rij getoond wordt. De syntax is wennen, eerlijk is eerlijk. Nu de uitleg. De lengte kunnen we zetten, want dat is de MEASURE. Welke lengte je dan wilt zetten wordt bepaald door de opgegeven DIMENSION. De rule die er staat kun je vrij vertalen naar: de lengte die wordt geïdentificeerd door wegen_id 1 en 5 oktober krijgt de waarde - 10. Het opgeven van de DIMENSION staat altijd tussen rechte haken. Nu is het toekennen van de waarde -10 natuurlijk volstrekt onzinnig, het gaat om het idee. Eigenlijk willen we de gemiddelde waarde van de overige rijen op deze plaats hebben. Aangezien zoiets in Excel mogelijk is, dan is dat met de MODEL clause ook mogelijk. In plaats van -10 zetten we dit in de rule: avg (lengte) [1, any] Dit vertaald naar: de gemiddelde waarde van de lengtes met de dimension wegen_id 1 voor alle data in de resultaat set. Het totaal plaatje ziet er dan zoals onderstaande query uit, als we voor beide wegen de lengte willen voorspellen voor volgende week dinsdag. 4 from files 6 model 7 dimension by (wegen_id, datum) 8 measures (lengte) 9 rules ( 10 lengte [1 11,to_date ('05-10-2010 07:00', 'dd-mm-yyyy hh24:mi') 12 ] = avg (lengte) [1, any]

13,lengte [2 14,to_date ('05-10-2010 07:00', 'dd-mm-yyyy hh24:mi') 15 ] = avg (lengte) [2, any] 16 ) 17 ; 2 05-OCT-10 0 1 05-OCT-10 6.33333333 Krachtig, niet waar? Wel jammer dat we de rule twee keer moeten opnemen. Ook jammer als er op een gegeven moment een weg bij komt en we de query moeten uitbreiden. Is daar nu niets voor? Uiteraard is daar iets voor. Net als bij analytische functies kun je ook bij de MODEL clause een PARTITION BY clause opnemen. Met de PARTITION BY clause kun je de resultaat set in logische stukken verdelen. Het meest logische in dit voorbeeld zou dan ook het wegen_id zijn. Per wegen_id wil je een bepaalde berekening laten uitvoeren. 4 from files 6 model 7 partition by (wegen_id) 8 dimension by (datum) 9 measures (lengte) 10 rules ( 11 lengte [to_date ('05-10-2010 07:00', 'dd-mm-yyyy hh24:mi')] 12 = avg (lengte) [any] 13 ) 14 ; 1 05-OCT-10 6.33333333 2 05-OCT-10 0 6 rows selected.

De partition clause is toegevoegd op regel 7. Omdat we deze clausule toevoegen kunnen we de wegen_id uit de DIMENSION clause halen (regel 8). Het gevolg hiervan is dat de dimension die we gebruiken om de lengte te manipuleren slechts één waarde hoeft te bevatten, namelijk de datum (regel 11). Dat het nogal complex kan worden met de MODEL clause zal je niet verwonderen. Onderstaand is een voorbeeld om een overzicht te krijgen van de files op de wegen voor volgende week. Hierin worden nog meer mogelijkheden van de MODEL clause getoond, zoals het reference model (regels 8 tot en met 16), het gebruik van het reference model (regels 22 tot en met 25) en de iteratie van de rules (regel 21). 3, to_char (datum, 'Day' 4,'nls_date_language=dutch') dag 5, lengte 6 from files 7 model return updated rows 8 reference dagen 9 on (select rownum rn 10, trunc (sysdate + 7, 'iw') + rownum - 1 11 + interval '7' hour volgende_week 12 from dual 13 connect by level <= 7 14 ) 15 dimension by (rn) 16 measures (volgende_week) 17 main result 18 partition by (wegen_id) 19 dimension by (datum, to_char (datum, 'Day') dd) 20 measures (lengte) 21 rules iterate (7)( 22 lengte [dagen.volgende_week [iteration_number + 1] 23,to_char (dagen.volgende_week [iteration_number + 1], 'Day') 24 ] = avg (lengte) [any 25,to_char (dagen.volgende_week [iteration_number + 1] 26,'Day') 27 ] 28 ) 29 order by wegen_id, datum 30 ; DAG ---------- --------- --------- ---------- 1 04-OCT-10 Maandag 5.66666667 1 05-OCT-10 Dinsdag 6.33333333

14 rows selected. 1 06-OCT-10 Woensdag 1 07-OCT-10 Donderdag 1 08-OCT-10 Vrijdag 9 1 09-OCT-10 Zaterdag 9 1 10-OCT-10 Zondag 12 2 04-OCT-10 Maandag 2 05-OCT-10 Dinsdag 0 2 06-OCT-10 Woensdag 2 07-OCT-10 Donderdag 2 08-OCT-10 Vrijdag 2 09-OCT-10 Zaterdag 2 10-OCT-10 Zondag Voor een volledige beschrijving van de MODEL clause leent dit artikel zich niet, maar hopelijk heeft het wel je interesse gewekt om eens naar deze krachtige syntax nader te kijken. Ook al hebben we de ANWB nu geholpen met het voorspellen van de lengte van de files, het wordt er niet leuker op om in de file te staan.