C.T. de Groot J.G. Klein Spoedcursus SQL met MS-Access Wolters-Noordhoff Groningen/Houten
Ontwerp binnenwerk: Studio Wolters-Noordhoff, Groningen Wolters-Noordhoff bv voert voor het hoger onderwijs de imprints Wolters-Noordhoff, Stenfert Kroese, Martinus Nijhoff en Vespucci. Eventuele op- en aanmerkingen over deze of andere uitgaven kunt u richten aan: Wolters- Noordhoff bv, Afdeling Hoger Onderwijs, Antwoordnummer 13, 9700 VB Groningen, e-mail: info@wolters.nl 0 1 2 3 4 5 / 10 09 08 07 06 Copyright 2006 Wolters-Noordhoff bv Groningen/Houten, The Netherlands. Behoudens de in of krachtens de Auteurswet van 1912 gestelde uitzonderingen mag niets uit deze uitgave worden verveelvoudigd, opgeslagen in een geautomatiseerd gegevensbestand of openbaar gemaakt, in enige vorm of op enige wijze, hetzij elektronisch, mechanisch, door fotokopieën, opnamen of enig andere manier, zonder voorafgaande schriftelijke toestemming van de uitgever. Voor zover het maken van reprografische verveelvoudigingen uit deze uitgave is toegestaan op grond van artikel 16h Auteurswet 1912 dient men de daarvoor verschuldigde vergoedingen te voldoen aan Stichting Reprorecht (postbus 3060, 2130 KB Hoofddorp, www.reprorecht.nl). Voor het overnemen van korte gedeelte(n) uit deze uitgave in bloemlezingen, readers en andere compilatiewerken (artikel 16 Auteurswet 1912) kan men zich wenden tot Stichting PRO (Stichting Publicatie- en Reproductierechten Organisatie, postbus 3060, 2130 KB Hoofddorp, www.cedar.nl/pro). Voor het overnemen van niet-korte gedeelte(n) dient men zich rechtstreeks te wenden tot de uitgever. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior written permission of the publisher.
Woord vooraf Deze syllabus wordt gebruikt om te leren werken met SQL, een vraagtaal die gegevens uit een gegevensverzameling (de database) haalt. Met SQL kunnen de gegevens uit de database op complexe wijze worden gecombineerd om tot de gewenste informatie te komen. Dit zogeheten aggregeren van gegevens tot de gewenste informatie kan binnen het softwarepakket MS-Access van Microsoft op twee verschillende manieren gerealiseerd worden. 1 De eerste mogelijkheid is gebruik te maken van de commando s van SQL. 2 De tweede mogelijkheid is de gebruiksvriendelijk Query By Example, een sterk gevisualiseerde omgeving waarbij in de executiefase een commando in SQL gegenereerd en uitgevoerd wordt. In deze syllabus worden beide mogelijkheden behandeld. De nadruk ligt op de SQL-commando s die ook in andere omgevingen dan die van Microsofts MS-Access gebruikt worden. De Query By Example (= QBE) hoort typisch bij MS-Access, in andere softwarepakketten zal de daar gehanteerde QBE er anders uitzien. Voor een goed gebruik van MS-Access is het nodig een aantal termen te kennen. Het overgrote deel wordt in de eerste hoofdstukken van deze syllabus behandeld. Voor de eenvoud van de bestudering zijn deze termen cursief afgedrukt. J.G. Klein, IJsselstein C.T. de Groot, Wijk bij Duurstede
Inhoud 1 Access starten, database openen en sluiten 5 2 Raadplegen van een bestand 8 2.1 Een query maken 8 2.2 SQL-commando 10 2.3 Het sorteren van de uitvoer 13 2.4 Het verwijderen van dubbele resultaten 15 2.5 Raadplegen met een enkelvoudige conditie 15 2.6 De samengestelde conditie 17 2.7 De samengestelde conditie met meer dan twee condities 19 2.8 Het gebruik van IN, BETWEEN, LIKE 20 2.9 Functies in SQL 22 2.10 Rekenen in SQL 24 3 Raadplegen van verschillende bestanden 26 3.1 Het koppelen van tabellen met een join 26 3.2 De sub-query 28 3.3 De sub-query, unieke mogelijkheden 30 4 Groeperen 32 4.1 Het definiëren van groepen: GROUP BY 32 4.2 Gebruik queryvenster 34 4.3 Selecties op groepen: HAVING 36 4.4 Gebruik queryvenster by HAVING 36 Bijlage De database van BitByBit 38 4 Spoedcursus SQL met MS-Access
1 Access starten, database openen en sluiten Start Access via de toolbar. Kies vervolgens voor Een bestaande database openen en selecteer de database BitByBit. Nadat de database is geopend wordt het Microsoft Access-venster zichtbaar. Dit venster laat zich opsplitsen in een menubalk (Bestand, Bewerken, Beeld, enzovoort), een databasewerkbalk (met een groot aantal knoppen voor standaardbewerkingen) en een databasevenster dat bij de geopende database hoort. Dit databasevenster bevat de objectknoppen Tabellen, Queries, Formulieren, Rapporten, Macro s en Modulen. Zie voor de gebruikte termen figuur 1.1. Figuur 1.1 Een venster van Access Inhoud bestand in gegevensbladweergave Om gegevens van de database te kunnen bekijken, moet je op de knop Tabellen klikken. De tabellen die bij de database horen, worden in alfabetische volgorde getoond. Je kunt de gewenste tabel selecteren door er op te klikken. Daarna kun je de inhoud van de tabel bekijken in het venster Gegevensbladweergave. Hiervoor moet je op de knop Openen klikken, die je kunt vinden aan de rechterzijde van het databasevenster. Zie figuur 1.2. Spoedcursus SQL met MS-Access 5
Figuur 1.2 Het venster Gegevensbladweergave in Access Het venster Gegevensbladweergave kan op de gebruikelijke wijze vergroot worden. De aanwijzer kan op verschillende manieren gebruikt worden om de gewenste records en velden zichtbaar te maken. Opdracht 1.1 Open het bestand Klant en ga na in welke stad Cohen Gebak is gevestigd. Keer vervolgens terug naar het databasevenster. Inhoud bestand met formulierweergave Met Microsoft Access kunnen gegevens op verschillende manieren worden weergegeven. In de zojuist behandelde werkwijze werden de gegevens via de knop Tabellen gepresenteerd in de Gegevensbladweergave. Een andere manier is de zogeheten Formulierweergave. Een voorbeeld is het formulier Klantenformulier. Probeer dit formulier zelf op te roepen. In figuur 1.3 zie je wat je op je scherm moet krijgen. 6 Spoedcursus SQL met MS-Access
Figuur 1.3 Klantenformulier Onder in het venster zitten de navigatieknoppen die op het formulier gebruikt worden om naar een ander record te gaan. In de formulierweergave is duidelijk zichtbaar dat de gegevens van slechts één record worden getoond, terwijl in de gegevensbladweergave verschillende records van een bestand worden gepresenteerd. Het is zeer eenvoudig om te wisselen van de ene naar de andere wijze van presenteren. Daarvoor moet je in de menubalk op de knop Beeld klikken en kun je naar believen van de formulierpresentatie naar de gegevenspresentatie gaan en weer terug. Spoedcursus SQL met MS-Access 7
2 Een bestand raadplegen Een bestand moet gebruikt worden. Een manier om het te gebruiken is het raadplegen van een bestand, dat wil zeggen het zoeken van gegevens in het bestand. Het raadplegen vindt plaats op basis van een vraag of query die aan de database wordt gesteld. Dit hoofdstuk en de volgende hoofdstukken handelen over de wijze waarop een query binnen Microsoft Access gemaakt kan worden. 2.1 Een query maken In het databasevenster bevindt zich de knop Query. Nadat je deze knop hebt geactiveerd, ben je in de gelegenheid een query aan te maken onder de knop Nieuw, die aan de rechterzijde te vinden is. Je kunt ook met de andere knoppen een eerder gemaakte query activeren of wijzigen. Als Nieuw is geactiveerd verschijnt het beeldscherm van figuur 2.1. Figuur 2.1 Een bestand raadplegen Nadat met de knop OK voor ontwerpweergave is gekozen, zoals ook in figuur 2.2 is gedaan, verschijnt het venster Tabel weergeven. 8 Spoedcursus SQL met MS-Access
Figuur 2.2 Het scherm Tabel weergeven Je kunt nu een tabel selecteren die via de knop Toevoegen zichtbaar wordt in het bovenste gedeelte van het venster. Je kunt het selecteren en toevoegen voor elke gewenste tabel herhalen. Wordt vervolgens op de knop Sluiten geklikt dan ontstaat het zogeheten queryvenster zoals te zien is in figuur 2.3. Figuur 2.3 Queryvenster Het queryvenster bestaat uit twee delen. In het bovenste deel worden de tabellen getoond waarop de query betrekking heeft. Het onderste deel wordt queryraster genoemd, en daarmee kan de query tot in detail worden opgebouwd. Opdracht 2.1 Voer voorgaande bewerkingen uit en plaats de tabel Producten in het queryvenster. Dubbelklik vervolgens op de veldnamen omschrijving, voorraad en prijs, waardoor deze drie velden opgenomen worden in het queryraster. Met deze opdracht is een zeer eenvoudige query gemaakt waarbij de gegevens over omschrijving, voorraad en prijs geselecteerd zullen worden. Het resultaat van de selectie wordt zichtbaar gemaakt door in de werkbalk de meest linkse knop in te drukken. De Spoedcursus SQL met MS-Access 9
tabel die nu verschijnt, wordt in Access dynaset genoemd, wat het antwoord op de query betekent. Je kunt weer terugkeren naar het queryvenster door weer op de meest linkse knop van de werkbalk te klikken. Zie figuur 2.4. Figuur 2.4 Knop Queryweergave Aan een query kan een naam gegeven worden, waardoor het mogelijk is een volgende keer opnieuw van de query gebruik te maken. De naam wordt pas bij het sluiten van het queryvenster gegeven. Bij de volgende opdrachten word je gevraagd met behulp van het queryvenster een eenvoudige query samen te stellen. Alle hiervoor genoemde stappen moeten bij elke vraag opnieuw worden uitgevoerd. Opdrachten 2.2 De secretaresse van BitByBit wil een adressenlijst hebben van alle medewerkers. Maak een adressenlijst waarin achtereenvolgens naam, adres en woonplaats zijn vermeld. Geef de query de naam query1. 2.3 Maak een lijst van de producten met de omschrijving en de bijbehorende prijs. 2.4 Geef een overzicht van de namen van de medewerkers en hun basissalaris. 2.5 Maak een telefoonlijst van alle klanten. Hoeveel klanten zitten er in het klantenbestand? 2.6 Welke medewerkers met welke functie en op welke afdeling krijgen geen verkoopprovisie, dat wil zeggen hebben een provisiepercentage gelijk aan 0? 2.2 SQL-commando Een query die op de hiervoor genoemde wijze gemaakt is, wordt eerst vertaald in een zogeheten SQL-commando. Het SQL-commando wordt vervolgens uitgevoerd om het resultaat van de query zichtbaar te maken, de dynaset. Je kunt het SQL-commando ook goed rechtstreeks intypen, zonder dat je uitgebreid gebruik maakt van het queryvenster. Het rechtstreeks intypen van SQL-commando s is minder gebruiksvriendelijk, maar daar staat tegenover dat er meer mogelijkheden zijn in SQL om het gewenste resultaat, de dynaset, te krijgen. Anderzijds is het ook zo dat het gebruik van het queryvenster sterk afhankelijk is van de software; het bestaat in deze vorm alleen binnen Microsoft Access. In andere pakketten heeft het queryvenster weer een andere vorm. De achterliggende 10 Spoedcursus SQL met MS-Access
SQL-commando s zijn echter hetzelfde. SQL geldt voor alle systemen. Start het queryvenster zoals in de vorige paragraaf is beschreven. Neem een of ander bestand, in het voorbeeld is dit PRODUCTEN maar het kan willekeurig zijn. Druk vervolgens op de rechterknop van de queryweergave in de werkbalk, zoals in figuur 2.5 is weergegeven. Door vervolgens SQL te selecteren kom je in het SQL-weergavescherm. Figuur 2.5 SQL-weergavescherm In de SQL-weergave kunnen commando s worden ingetypt. Er staat meestal al een commando, namelijk het commando om de opdracht van het queryvenster uit te voeren. In het voorbeeld verschijnt het, overigens niet correcte, SQL-commando: SELECT FROM producten; Dit commando kan aan elke wens worden aangepast, bijvoorbeeld om de selectie van de kolommen aan te geven, maar ook om een totaal nieuw SQL-commando in te typen. Je kunt bijvoorbeeld in de eerste regel een sterretje toevoegen, waardoor het wel een correct SQL-commando wordt: SELECT * FROM producten; Binnen de gegevensbladweergave kun je het resultaat van het commando bekijken. Dit is te vinden door weer op de meest linkse knop van de werkbalk te klikken, net zoals in figuur 2.4 is afgebeeld. De gegevensbladweergave van bovenstaand commando zie je in figuur 2.6. Spoedcursus SQL met MS-Access 11
Figuur 2.6 Gegevensbladweergave Van SQL zijn vele dialecten met elk hun eigen afspraken en notatiewijzen in omloop. Access vertaalt het ontwerp van een query naar een SQL-commando volgens de afspraken van Access-SQL. Het Access-SQL wijkt op enkele plaatsen af van het standaard ANSI- SQL. Het standaard-sql wordt echter volledig door Access begrepen. De SQL-commando s die hier gegeven worden, zijn van het kortere standaardtype. Werkwijze bij de beantwoorden opdrachten De volgende vragen moeten gemaakt worden met behulp van het SQL-weergavescherm. Probeer allereerst het commando uit door het gegevensblad te openen. Noteer het SQLcommando in de ruimte onder de vragen in de korte (ANSI-SQL) notatiewijze. Het resultaat hoeft uiteraard niet overgenomen te worden. In plaats van het SQL-commando op te schrijven kan dit ook gekopieerd en in een Word-document geplakt worden. Opdrachten 2.7 Maak een lijst waarop alle gegevens van de medewerkers staan. Bekijk het resultaat van de query in de Gegevensbladweergave. Noteer het SQL-commando. 2.8 Maak een lijst met daarop alle gegevens van de klanten. Noteer het SQL-commando. Gebruik hoofdletters of kleine letters Het maakt niet uit of SQL-queries met hoofdletters dan wel met kleine letters worden ingetoetst. Neem een commando als: SELECT naam, plaats ORDER BY naam; In deze syllabus worden SQL-begrippen (SELECT, FROM, ORDER BY enzovoort, dus de woorden van de taal SQL) met hoofdletters geschreven, terwijl de overige tekst met kleine letters wordt geschreven. Hieruit blijkt dat het ook goed is om met alleen maar hoofdletters of alleen maar met kleine letters de commando s te geven. Samenstellen SQL-commando In het vervolg van het boek zullen we voor het maken van SQL-commando s gebruikmaken van een aanpak die bestaat uit een viertal stappen: 1 Maak vanuit het databasevenster een nieuwe query en kies in de ontwerpweergave de tabel. 2 Kies vervolgens de velden die getoond moeten worden. 3 Schakel vervolgens naar de SQL-weergave om het SQL-commado aan te passen en/of uit te breiden. 4 Het resultaat van de query wordt zichtbaar gemaakt in de gegevensweergave. 12 Spoedcursus SQL met MS-Access
Opdrachten 2.9 Toon van de geregistreerde producten de omschrijving en de bijbehorende voorraad. Noteer het SQL-commando. 2.10 Geef in een overzicht de namen van de personeelsleden, met daarbij hun datum van indiensttreding. 2.3 Het sorteren van de uitvoer Het resultaat van een SQL-commando is in het algemeen ongesorteerd. Indien het resultaat van een SQL-commando wel gesorteerd moet worden, dan kun je gebruikmaken van de toevoeging ORDER BY aan het commando. Neem bijvoorbeeld het commando: SELECT naam, afdeling, functie ORDER BY naam; Het resultaat van dit commando toont een lijst van alle records van de tabel Medewerkers, maar nu gesorteerd. Naam Afdeling Functie Brendel Verkoop Vertegenwoordiger Cohen Verkoop Vertegenwoordiger Dirksen Assemblage Inpakker Doorman Financiën Administrateur Hendriks Verkoop Vertegenwoordiger Hoeben Verkoop Vertegenwoordiger Jansen Verkoop Vertegenwoordiger Tuinier Verkoop Verkoper Winkelman Magazijn Chef Wofsjong Inkoop Telefonist Ytzerda Verkoop Vertegenwoordiger Zachariassen Verkoop Verkoper Zweers Verkoop Vertegenwoordiger Een veldnaam achter de ORDER BY-component moet ook voorkomen in de SELECT-regel. In voorgaand voorbeeld komt het veld naam zowel achter de SELECT voor als achter de ORDER BY. In plaats van een veldnaam achter het onderdeel ORDER BY te zetten kan ook een getal worden gebruikt. Het getal verwijst naar de positie die de veldnaam inneemt achter het SELECT. Neem bijvoorbeeld het commando: SELECT naam, afdeling, functie ORDER BY 2; Hierin verwijst de 2 naar het veld afdeling, zodat op afdeling gesorteerd zal gaan worden. Een nummer in plaats van de veldnaam zelf is vooral handig als gerefereerd wordt naar een uitgebreide berekening achter de SELECT. Achter de toevoeging ORDER BY mogen ook verschillende veldnamen worden opgenomen, zoals in: SELECT productsoort, omschrijving, prijs FROM producten ORDER BY productsoort, omschrijving; Het met dit commando verkregen overzicht is tweemaal gesorteerd: eerst op productsoort en daarbinnen op de omschrijving, zie figuur 2.7. Spoedcursus SQL met MS-Access 13
Figuur 2.7 Overzicht In plaats van de veldnamen achter het onderdeel ORDER BY te zetten, kan door middel van getallen worden gerefereerd naar de posities die de veldnamen innemen achter het SELECT-onderdeel: SELECT functie, naam, plaats ORDER BY 1,2; Opdrachten 2.11 Voer het voorgaande commando uit. Let op de wijze waarop bij meervoudig sorteren het resultaat op het scherm wordt afgebeeld. 2.12 Geef in een overzicht de namen van de personeelsleden, met daarbij hun basissalaris. Sorteer de lijst op achternaam. Noteer het bijbehorende SQL-commando. 2.13 Er is een verschil tussen de volgende twee commando s. Noteer het verschil tussen beide commando s. SELECT plaats, naam FROM klanten ORDER BY 2,1; SELECT plaats, naam FROM klanten ORDER BY 1,2; 2.14 Noteer het verschil (als er een verschil is) tussen de volgende vier SQL-commando s: SELECT naam, basissalaris ORDER BY basissalaris; SELECT naam, basissalaris ORDER BY basissalaris DESC; SELECT naam, basissalaris ORDER BY basissalaris ASC; SELECT naam, basissalaris ORDER BY 2 ASC, 1 ASC; 14 Spoedcursus SQL met MS-Access
2.4 Het verwijderen van dubbele resultaten Als resultaat van een SELECT-commando kunnen dubbele rijen worden getoond. Iemand wil een overzicht van welke functies er binnen BitByBit bestaan. Dit overzicht verschijnt op het scherm na een commando als: SELECT functie ; Bij een dergelijk commando kunnen dezelfde functies verschillende keren voorkomen. Soms kan het fraaier zijn dit meervoudig voorkomen in de uitvoer te vermijden. Men kan dit elimineren met de DISTINCT-operator: SELECT DISTINCT functie ; Opdrachten 2.15 Noteer het commando dat een lijst geeft van verschillende plaatsen waarin klanten van het bedrijf gevestigd zijn. Een plaats mag maar één keer in de lijst voorkomen. Is het overzicht gesorteerd? 2.16 De vraag is welke klanten orders hebben geplaatst. Noteer het commando dat zo n lijst maakt, waarbij alleen het klantnummer getoond wordt. Gebruik het bestand Verkooporders. 2.17 Welke zijn de verschillende basissalarissen? Sorteer het overzicht! 2.5 Raadplegen met een enkelvoudige conditie In de voorgaande oefeningen werden alle records uit het bestand op het beeldscherm geplaatst. De meeste bestanden bevatten vele records, veel meer in elk geval dan er ruimte op één beeldscherm is. SQL is met name bruikbaar als je een overzicht wilt van een beperkt aantal records. Denk bijvoorbeeld aan de situatie dat iemand alleen maar geïnteresseerd is in de gegevens van de klanten die in Utrecht zijn gevestigd. Wanneer je dit soort selecties gaat maken, kan dat binnen SQL door het onderdeel WHERE toe te voegen aan het SELECT-commando. Met de WHERE-component wordt een voorwaarde of conditie gedefinieerd waarmee men aangeeft welke gegevens moeten worden geraadpleegd. We beginnen met de eenvoudigste vorm: de enkelvoudige conditie. Wanneer een conditie wordt samengesteld, kan gebruik worden gemaakt van zes operatoren: 1 < is kleiner dan; 2 > is groter dan; 3 = is gelijk aan; 4 <= is kleiner dan of gelijk aan; 5 >= is groter dan of gelijk aan; 6 <> is ongelijk aan. In het volgende voorbeeld wordt een commando gegeven dat een lijst produceert van alle artikelen waarvan de huidige voorraad vrij klein is, in dit geval minder dan zes stuks: SELECT omschrijving, prijs, voorraad FROM producten WHERE voorraad < 6; Spoedcursus SQL met MS-Access 15
Omschrijving Prijs Voorraad Geluidskaart 230,00 5 Pentium 90 mh 2.010,00 5 Pentium 120 mh 2.450,00 3 Pentium 300 mh 2.900,00 5 Pc 486-dx 150 mh 1.200,00 2 PowerSystem P100 690,00 4 PowerSystem P120 780,00 3 Het veld voorraad is een numeriek datatype. Met een numeriek datatype kan worden gerekend. In de voorraadkolom is te zien dat aan het criterium: voorraad <6 wordt voldaan. Het SQL-commando kan ook met de ontwerpweergave worden gemaakt, zoals te zien is in figuur 2.8. Figuur 2.8 Commando in Ontwerpweergave Het volgende voorbeeld is een commando dat een gesorteerde lijst produceert van klanten die in Landsmeer zijn gevestigd: SELECT naam, adres, plaats FROM klanten WHERE plaats = Landsmeer ORDER BY naam; Probeer dit commando op te bouwen via het queryvenster: Het veld plaats is een alfanumeriek datatype. De waarde die een alfanumeriek veld kan aannemen wordt omsloten door aanhalingstekens. Het resultaat van de query kan weer zichtbaar worden gemaakt in de gegevensbladweergave. 16 Spoedcursus SQL met MS-Access
Naam Adres Plaats Accent Uitgevers Hoogheuvelweg 20 Landsmeer Basis Centrum Kraanenstraat 76 Landsmeer Lasschuyt Q.A. Salieweg 83 Landsmeer Opdrachten 2.18 Maak een lijst van de klanten die gevestigd zijn in Sappemeer. Zet op de uitvoer de klantnaam, het adres en de vestigingsplaats. Noteer het SQL-commando. 2.19 Van welke artikelen zijn er meer dan 30 stuks in voorraad? Noteer het SQL-commando. 2.20 Welke verkooporders hebben een orderbedrag van meer dan 20.000 euro? Noteer het SQL-commando. Datumveld Het volgende voorbeeld is bedoeld om aan te geven hoe je gebruik kunt maken van een datumveld. De vraag is: welke medewerkers zijn al vóór juli 1988 in dienst getreden? De datum wordt ingevoerd als: 01/07/1988. Het SQL-commando is: SELECT naam, afdeling, functie, datumin WHERE datumin<#1/7/88#; Naam Adeling Functie Datumin Winkelman Magazijn Chef 1/24/85 Ytzerda Verkoop Vertegenwoordiger 5/17/85 Doorman Financiën Administrateur 12/2/86 Het veld datumin is van het datatype datum. De waarde die de datum kan aannemen, moet dan worden omsloten door hekjes, zoals #1/7/88#. Let op: een datumveld moet altijd een echt bestaande datum bevatten. De datum #0/0/88# bijvoorbeeld bestaat niet en geeft een foutmelding. Ook de datum #30/2/88# behoort tot de foutieve data. Opdrachten 2.21 Welke personeelsleden zijn na 1991 in dienst getreden? Noteer het SQL-commando. 2.22 Maak een lijst met verkooporders die na 2002 geplaatst zijn. 2.6 De samengestelde conditie Uiteraard is het nodig dat je commando s kunt geven met een samengestelde conditie. Een samengestelde conditie is een conditie die aan meer dan één voorwaarde moet voldoen. Denk bijvoorbeeld aan de medewerker van de afdeling Verkoop die een overzicht wil maken van al zijn verkooporders in een bepaalde week met een orderbedrag boven de 10.000 euro. De twee condities zijn als eerste de afdeling Verkoop en als tweede het orderbedrag groter dan 10.000. Wanneer je in SQL een samengestelde conditie wilt definiëren, moet je gebruikmaken van de operatoren AND of OR of van een combinatie ervan. Allereerst worden in deze paragraaf SQL-opdrachten behandeld die uit twee condities bestaan. AND-operator De heer Winkelman heeft het idee dat de magazijnvoorraad van een aantal goederen een hoog bedrag vertegenwoordigt. Hij wil daarom een lijst maken van artikelen waarvan de verkoopprijs 500 euro of meer bedraagt en waarvan er meer dan 10 stuks in voor- Spoedcursus SQL met MS-Access 17
raad zijn. Voor de beantwoording van deze vraag wordt van de AND-operator gebruikgemaakt: SELECT omschrijving, prijs, voorraad FROM producten WHERE prijs >= 500 AND voorraad > 10; Omschrijving Prijs Voorraad Beeldscherm VGA 745,00 40 HardDisk 5,2Gb 4.603,00 12 PowerSystem P170 1.350,00 14 OR-operator Een volgend voorbeeld toont het gebruik van de OR-operator. Stel, het is nu 12 februari 1997. De vraag is welke klanten gisteren of eergisteren orders hebben geplaatst. Het commando dat het gewenste antwoord geeft, is: SELECT klantnr, orderdat FROM verkooporders WHERE orderdat = #11/02/2003# OR orderdat = #10/02/2003#; Opdrachten 2.23 Geef het commando waarmee een overzicht wordt gegeven van de verkooporders in week 14 waarbij het orderbedrag boven de 10.000 euro uitsteeg. 2.24 Gevraagd wordt: een overzicht van alle klanten in Loosdrecht en Weesp. Welke van de twee commando s is het juiste? SELECT naam, plaats FROM klanten WHERE plaats = Loosdrecht AND plaats = Weesp ; SELECT naam, plaats FROM klanten WHERE plaats = Loosdrecht OR plaats = Weesp ; 2.25 Wat is het verschil tussen de volgende twee commando s? SELECT omschrijving, prijs, voorraad FROM producten WHERE prijs >= 100 AND voorraad > 10; SELECT omschrijving, prijs, voorraad FROM producten WHERE prijs >= 100 OR voorraad > 10; 2.26 Welke verkooporders zijn er geplaatst in de periode 26 augustus 2002 tot en met 5 september 2002? Noteer het SQL-commando. 18 Spoedcursus SQL met MS-Access
2.27 Maak een overzicht waarin de namen, de functie en de afdeling van de vertegenwoordigers en de verkopers staan vermeld. Sorteer het overzicht op naam van de medewerker. 2.7 De samengestelde conditie met meer dan twee condities Het is natuurlijk ook mogelijk om meer dan twee voorwaarden te koppelen in één samengestelde conditie. Daarbij kunnen de logische operatoren AND en OR één of verschillende malen, al of niet gecombineerd, voorkomen. Neem bijvoorbeeld de volgende situatie waarin drie condities verscholen zitten: Een functionaris van personeelszaken wenst een lijst van alle vertegenwoordigers met een basissalaris tussen de 40.000 en 50.000 euro. Het SQL-commando dat antwoord op de vraag geeft is: SELECT naam, functie, basissalaris, datumin WHERE functie = Vertegenwoordiger AND basissalaris >= 40000 AND basissalaris <= 50000; Naam Functie Basissalaris Datumin Hendriks Vertegenwoordiger 45.000,00 15-2-88 Brendel Vertegenwoordiger 45.000,00 7-5-89 Hoeben Vertegenwoordiger 45.000,00 5-11-90 Zweers Vertegenwoordiger 45.000,00 18-4-91 Jansen Vertegenwoordiger 45.000,00 2-6-91 Cohen Vertegenwoordiger 47.000,00 12-5-93 In een samengestelde conditie met meer dan twee voorwaarden moet je heel vaak gebruikmaken van haakjes om het juiste commando te kunnen geven. Als we een lijst wensen van alle Vertegenwoordigers uit Gouda of Delft dan levert het volgende SQLcommando wel een lijst (immers, het commando is syntactisch juist gesteld), maar het is helaas de verkeerde: SELECT naam, plaats, functie WHERE plaats = Gouda OR plaats = Delft AND functie = Vertegenwoordiger ; Opdrachten 2.28 Voer dit commando uit. In het resultaat van het commando op het scherm is te zien dat er medewerkers zijn die niet tot de vertegenwoordigers behoren. Dat is niet gevraagd, het commando is daarom onjuist. Het commando kan wel correct worden gemaakt door op de juiste plek haakjes te zetten. Neem bijvoorbeeld de twee volgende commando s: SELECT naam, plaats, functie WHERE (plaats = Gouda OR plaats = Delft ) AND functie = Vertegenwoordiger ; SELECT naam, plaats, functie WHERE plaats = Gouda OR (plaats = Delft AND functie = Vertegenwoordiger ); Spoedcursus SQL met MS-Access 19
2.29 Welke van de twee commando s uit opdracht 2.27 geeft wel de juiste lijst? Een belangrijke afspraak is: Gebruik in een samengestelde conditie waarin een OR-operator zit altijd haakjes om de bedoeling duidelijk te maken. Beter is, indien mogelijk, om de IN-operator te gebruiken. Deze operator wordt in de volgende paragraaf behandeld. 2.30 Welke medewerkers zijn in 1991 of 1992 in dienst gekomen als vertegenwoordiger of als verkoper? Plaats op dit overzicht alleen de naam, de functie en de datum van indiensttreding. Noteer het SQL-commando. 2.8 Het gebruik van IN, BETWEEN, LIKE Soms is het wenselijk bij een samengestelde conditie een aantal mogelijke waarden voor een veld op te geven. Zo zouden we een lijst kunnen maken van klanten in zes gemeenten: SELECT naam, adres, plaats FROM klanten WHERE plaats = Loosdrecht OR plaats = Mijdrecht OR plaats = Landsmeer OR plaats = Weesp OR plaats = Bussum OR plaats = Abcoude ; Naam Adres Plaats Algemene Kantoor Grootestraat 56 Loosdrecht Interieur Totaal Kennemerweg 89 Mijdrecht Accent Uitgevers Hoogheuvelweg 20 Landsmeer Countinho Continu Colderweg 56 Mijdrecht Lada Rijgenot Visstraat 60 Loosdrecht Basis Centrum Kraanenstraat 76 Landsmeer Akkerman D. Leijenburglaan 96 Weesp Lasschuyt Q.A. Salieweg 83 Landsmeer Het is mogelijk dergelijke commando s te vervangen door een ander en zeer handig SQLcommando met een IN-operator: SELECT naam, adres, plaats FROM klanten WHERE plaats IN ( Loosdrecht, Mijdrecht, Landsmeer, Weesp, Bussum, Abcoude ); Voorgaand voorbeeld laat zien dat het mogelijk is een verzameling in het commando op te nemen, in dit geval de verzameling van gewenste steden. Binnen SQL kan een IN-operator gecombineerd worden met de NOT-operator. Neem bijvoorbeeld het volgende commando om een lijst van adressen te krijgen van klanten die nu juist niet in de verzameling plaatsen wonen: SELECT naam, adres, plaats FROM klanten WHERE plaats NOT IN ( Loosdrecht, Mijdrecht, Landsmeer, Weesp, Bussum, Sappemeer ) ORDER BY plaats; 20 Spoedcursus SQL met MS-Access
Naam Adres Plaats Broeckhove T.H. Waterstraat 2 Almelo Nieuwveen K.G. Rondweg 125 Castricum Van der Valk Complex Ventweg 101 Elspeet Tellegen W.U. Wijdeblik 60 Nieuw-Vennep Theo Meubelpaleis Piersmaweg 101 Nieuw-Vennep Leonardo P.P. Kasteelweg 50 Oirschot Bakker Kantoor Teylerslaan 67 Petten Touber Vleespaleis Benedictijn 45 Rolde Classique Stijlinter Eiberlaan 201 St. Pancras Alleman service Bredesloot 40 St. Pancras Commelin Feestart Gijp 140 Vierhuizen Expert Service Meierij 406 Winschoten Cuypers Y. Pijnackerstraat 64 Yerseke Ook de BETWEEN-operator maakt sommige SQL-formuleringen eenvoudiger en daardoor beter leesbaar. De volgende twee SQL-commando s geven hetzelfde resultaat op het beeldscherm: SELECT naam, functie, basissalaris, datumin WHERE basissalaris >= 40000 AND basissalaris <= 50000; SELECT naam, functie, basissalaris, datumin WHERE basissalaris BETWEEN 40000 AND 50000; Naam Functie Basissalaris Datumin Wofsjong Telefonist 45.000,00 5-1-92 Hendriks Vertegenwoordiger 45.000,00 15-2-88 Brendel Vertegenwoordiger 45.000,00 7-5-89 Dirksen Inpakker 41.000,00 9-10-89 Hoeben Vertegenwoordiger 45.000,00 5-11-90 Zweers Vertegenwoordiger 45.000,00 18-4-91 Jansen Vertegenwoordiger 45.000,00 2-6-91 Tuinier Verkoper 41.000,00 13-5-92 Cohen Vertegenwoordiger 47.000,00 12-5-93 Zachariasse Verkoper 45.000,00 17-7-93 De BETWEEN is duidelijker en handiger in het gebruik. Ook de BETWEEN-operator mag weer worden gecombineerd met de NOT-operator, zoals in het volgend voorbeeld te zien is: SELECT naam, functie, datumin WHERE datumin NOT BETWEEN #01/01/1988# AND 01/01/1991# ORDER BY datumin; Spoedcursus SQL met MS-Access 21
Naam Functie Datumin Winkelman Chef 24-1-85 Ytzerda Vertegenwoordiger 17-5-85 Doorman Administratie 2-12-86 Zweers Vertegenwoordiger 18-4-91 Jansen Vertegenwoordiger 2-6-91 Wofsjong Telefonist 5-1-92 Tuinier Verkoper 13-5-92 Cohen Vertegenwoordiger 12-5-93 Zachariassen Verkoper 17-7-93 Het zoeken in de database lukt alleen als men precies weet wat men moet vinden. Als bijvoorbeeld een spelfout in de naam zit zijn de gegevens bijna niet meer te achterhalen. De LIKE-operator vangt dit probleem voor een groot gedeelte op. Zo is het mogelijk dat iemand gegevens moet hebben van een klant van wie de naam niet meer precies bekend is, maar van wie men nog wel weet dat er Valk in voorkwam. Met het gebruik van de LIKE-operator in een voorwaarde is het mogelijk slechts een gedeelte van een veldwaarde op te geven: SELECT naam, adres, plaats FROM klanten WHERE naam LIKE *Valk* ; Naam Adres Plaats Van der Valk Complex Ventweg 101 Elspeet De *-tekens geven aan dat zowel voor als achter de letters Valk willekeurige tekencombinaties kunnen voorkomen. Het *-teken wordt een joker of wildcard genoemd. Opdrachten 2.31 Welke medewerkers hebben een modaal basissalaris van tussen de 45.000 en 50.000 euro? Gebruik BETWEEN. Vraag: worden de grenswaarden wel of niet meegerekend? Noteer het SQL-commando. 2.32 Welke klanten met Kantoor in de naam zijn er in het klantenbestand opgenomen? Gebruik LIKE. 2.33 Welke medewerkers wonen niet in één van de vier grote steden Dordrecht, Gouda, Rotterdam en Delft? Gebruik NOT IN. 2.9 Functies in SQL De tot nu behandelde SQL-commando s leverden informatie op die gepresenteerd werd in de vorm van rijen uit de verschillende bestanden. De commando s zijn nog niet voldoende om alle gewenste informatie uit de database te halen. Het simpel tellen van records is bijvoorbeeld alleen mogelijk door gebruik te maken van de zogeheten functies binnen SQL. Er zijn vijf functies gedefinieerd waarmee je acties, zoals berekeningen, kunt uitvoeren op de gegevenswaarden binnen een kolom: AVG - gemiddelde SUM - som MIN - minimum MAX - maximum COUNT - aantal 22 Spoedcursus SQL met MS-Access
De standaardfuncties leveren allemaal een waarde op in plaats van een reeks waarden bij de eerdergenoemde commando s. AVG Neem bijvoorbeeld de vraag wat het gemiddelde salaris is van alle medewerkers, dan is het commando: SELECT AVG(basissalaris) ; Expr1000 53.230,77 We zien dat de kolom basissalaris waarover het gemiddelde wordt berekend, vermeld moet worden tussen de haakjes. De gegevenswaarden in de kolom waarover het gemiddelde berekend wordt, moeten uiteraard getallen bevatten. Neem het commando: SELECT AVG(basissalaris) WHERE afdeling = Verkoop ; Hierbinnen worden eerst alle rijen geselecteerd waarin de gegevens van de verkopers zijn geregistreerd. Vervolgens wordt uit die verzameling het gemiddelde berekend van de gegevenswaarden van de kolom basissalaris : Expr1000 48.444,44 SUM De gegevenswaarden waarover gesommeerd wordt, moeten ook numeriek zijn. Neem voor het gebruik van de SUM het volgende voorbeeld: het basissalaris in het bestand MEDEWERKERS is het salaris op jaarbasis, afgezien van de provisie. De volgende query berekent het totaal aan vaste salariskosten dat jaarlijks aan de medewerkers wordt betaald: SELECT SUM(basissalaris) ; Expr1000 692.000,00 MAX en MIN De gevenswaarden waarvan de maximale of minimale waarde bepaald wordt, hoeven niet per se numeriek te zijn, ze mogen ook data of namen bevatten. Wil je bijvoorbeeld weten wat het hoogste basissalaris is dan wordt de query: SELECT MAX(basissalaris) ; Expr1000 89.000,00 Spoedcursus SQL met MS-Access 23
De volgende query geeft de prijs van het goedkoopste artikel: SELECT MIN(prijs) FROM producten; Expr1000 99,75 COUNT De functie telt het aantal records, geen gegevenswaarde. Wil iemand bijvoorbeeld weten hoeveel medewerkers er momenteel in dienst zijn, dan wordt het commando: SELECT COUNT(*) ; Expr1000 13 Achter de functie COUNT staat tussen de haakjes een * vermeld. Dit komt omdat men het aantal records wil tellen. Het symbool * staat eigenlijk voor het gehele record. Opdrachten 2.34 Hoeveel verkooporders zijn er in de eerste helft van 2002 geplaatst? Noteer het SQL-commando. 2.35 Wat is het totaalbedrag van deze verkooporders? 2.36 Wat is het gemiddelde bedrag aan verkooporder in 2002? 2.37 In welke verschillende steden zijn klanten van BitByBit gevestigd? 2.38 Wat zijn de totale loonkosten per jaar, uitgaande van de basissalarissen? 2.39 Wat is het gemiddelde salaris van de Vertegenwoordigers? 2.10 Rekenen in SQL In de SELECT- en in de WHERE-component mogen rekenkundige bewerkingen voorkomen. De rekenkundige operatoren +, -, * en / kunnen voor dit doel worden gebruikt. Deze operatoren staan achtereenvolgens voor: + optellen - aftrekken * vermenigvuldigen / delen In het volgende voorbeeld wordt gebruikgemaakt van de rekenkundige operatoren. De heer Winkelman is geïnteresseerd in de artikelen die een hoge magazijnwaarde vertegenwoordigen. De vraag is een lijst van alle artikelen te geven, gesorteerd op de waarde van de voorraad: SELECT omschrijving, prijs, voorraad, prijs*voorraad FROM producten ORDER BY 4; 24 Spoedcursus SQL met MS-Access
Omschrijving Prijs Voorraad Expr1 Geluidskaart 230,00 5 1.150,00 PowerSystem P120 780,00 3 2.340,00 Muis 99,75 24 2.394,00 Pc 486-dx 150 mh 1.200,00 2 2.400,00 PowerSystem P100 690,00 4 2.760,00 HardDisk 2,2Gb 330,00 14 4.620,00 Toetsenbord 124,00 45 5.580,00 PowerSystem P150 960,00 7 6.720,00 Pentium 120 mh 2.450,00 3 7.350,00 PowerSystem P160 1.150,00 7 8.050,00 PowerSystem P200 1.550,00 6 9.300,00 Pc 486-dx 120 mh 1.100,00 9 9.900,00 Pentium 90 mh 2.010,00 5 10.050,00 Pentium 300 mh 2.900,00 5 14.500,00 Pentium 200 mh 2.600,00 6 15.600,00 PowerSystem P170 1.350,00 14 18.900,00 Beeldscherm VGA 745,00 40 29.800,00 HardDisk 5,2Gb 4.603,00 12 55.236,00 Mini Multi Media 9.550,00 7 66.850,00 Mini Multi Media 10.250,00 9 92.250,00 Opdrachten 2.40 Wat is het totaal van de salariskosten dat maandelijks aan de medewerkers wordt uitbetaald? Ga uit van de basissalarissen. Spoedcursus SQL met MS-Access 25
3 Raadplegen van verschillende bestanden Tot nu toe hadden alle SELECT-commando s betrekking op het raadplegen van gegevens uit slechts één bestand. In dit hoofdstuk wordt besproken hoe je een SQL-commando kunt construeren als de informatie in verschillende bestanden is opgeslagen. Daarvoor biedt SQL twee mogelijkheden: de JOIN en de SUB-QUERY. 3.1 Het koppelen van tabellen met een join Een database bestaat uit verschillende tabellen met een zeer duidelijke structuur: de tabellen zijn met relaties aan elkaar gekoppeld. In hoofdstuk 2 waren alle queries van toepassing op slechts één tabel. Bij een join worden twee of verschillende tabellen samengevoegd tot een tijdelijk bestand, waarop de reeds behandelde SQL-commando s toegepast kunnen worden. Bestanden kunnen alleen op zinvolle wijze samengevoegd worden als er gegevenswaarden zijn die in zowel het ene als in het andere bestand voorkomen. Binnen Access kan op zeer eenvoudige wijze een JOIN-constructie gemaakt worden. Om de JOIN samen te stellen wordt gebruikgemaakt van de ontwerpweergave (queryvenster). Allereerst worden in het queryvenster de tabellen toegevoegd waarop de vraag betrekking heeft. De relatie tussen de tabellen zal door Access in het queryvenster worden getoond. Het gebruik van de join van twee tabellen wordt met een voorbeeld toegelicht. De manager van de afdeling Verkoop is geïnteresseerd in de namen van de medewerkers die in week 21 een verkooporder noteerden. Voor het antwoord op deze vraag zal in twee tabellen gezocht moeten worden. In de tabel Verkooporders zal het weeknummer moeten worden gezocht, terwijl in de tabel Medewerkers de namen van de medewerkers moeten worden gevonden. Voor het maken van een commando zijn de tabellen Verkooporders en Medewerkers nodig. Zie figuur 3.1. Figuur 3.1 Queryvenster voor JOIN 26 Spoedcursus SQL met MS-Access
In het queryvenster is de relatie tussen de twee tabellen zichtbaar geworden. Uiteraard is Access daartoe in staat enkel en alleen omdat de twee tabellen een gemeenschappelijk veld bevatten: Mednr. In het queryraster kunnen de attributen worden opgegeven die in het uiteindelijke resultaat zichtbaar moeten worden (Naam en Weeknr), alsmede het criterium (weeknr=21) dat in de vraagstelling is opgesloten. Deze toevoegingen geven het volgende resultaat (zie figuur 3.2). Figuur 3.2 Een JOIN met een voorwaarde Het resultaat van de query is: Naam Weeknr Hendriks 21 Zachariassen 21 Zweers 21 De query van het queryvenster wordt in een een SQL-commando vertaald. Voor voorgaande join is het SQL-commando: SELECT DISTINCTROW medewerkers.naam, verkooporders.weeknr INNER JOIN verkooporders ON medewerkers.mednr = verkooporders.mednr WHERE (((verkooporders.weeknr)=21)); Van SQL zijn vele dialecten met elk hun eigen afspraken en notatiewijzen in omloop. MS- Access vertaalt het ontwerp van een query naar een SQL-commando volgens de afspraken van Access-SQL. Daarbij vallen drie zaken op: 1 In de SELECT-regel plaatst Access altijd volledig de tabelnaam + veldnaam. 2 In de FROM-regel worden de tabellen genoemd waarop de vraag betrekking heeft. Bovendien wordt in de regel ook de relatie tussen de bestanden aangegeven (de JOIN gemaakt). 3 In de WHERE-regel worden de criteria opgenomen. Spoedcursus SQL met MS-Access 27
Het voorgaande SQL-commando kan worden vervangen door het kortere ANSI-SQL: SELECT naam, weeknr, verkooporders WHERE medewerkers.mednr = verkooporders.mednr AND verkooporders.weeknr=21; Opdrachten 3.1 Maak een lijst waarop de namen, adressen, vestigingsplaatsen en orderdatum staan vermeld van de klanten die een verkooporder hebben geplaatst van meer dan 30.000 euro. Sorteer het resultaat op orderdatum. Noteer het SQL-commando. 3.2 Men wil een lijst verkrijgen van de klanten die in week 21 een verkooporder hebben geplaatst. Op deze lijst moeten zowel de naam als het klantnummer van de desbetreffende klanten worden getoond. Noteer de JOIN-constructie. 3.3 Maak een lijst waarop de namen en de klantennummers vermeld staan van de klanten die een order hebben geplaatst van meer dan 12.000 euro. Noteer het juiste commando. 3.4 Maak een lijst met naam, adres, plaats, postcode en klantnummer van goede klanten. Dat zijn klanten die orders hebben geplaatst met een orderbedrag groter dan 20.000 euro. 3.5 De heer Hendriks heeft als verkoper goede resultaten geboekt. Geef de namen van de klanten, de orderdata en de orderbedragen van de verkooporders die door zijn toedoen een verkooporder hebben geplaatst. Sorteer het overzicht. Raadpleeg voor deze query drie tabellen. Noteer het SQL-commando. 3.2 De sub-query Een sub-query is een vraag binnen een vraag. Dit zal allereerst worden toegelicht met een voorbeeld van twee aparte commando s om het gewenste resultaat te verkrijgen. Indien men bijvoorbeeld een overzicht wil van de namen van alle medewerkers die in week 13 een verkooporder noteerden, dan kan dat gerealiseerd worden door twee queries te geven: SELECT mednr FROM verkooporders WHERE weeknr=13; Vervolgens noteert men het resultaat op een kladpapiertje: (214, 718, 380) en wordt de tweede query opgesteld om het uiteindelijk gewenste resultaat te verkrijgen: SELECT naam WHERE mednr IN (214, 718, 380); Deze twee commando s kunnen worden gecombineerd in één SQL-commando: SELECT naam WHERE mednr IN (SELECT mednr FROM verkooporders WHERE weeknr=13); Merk op dat het oorspronkelijke tweede commando als eerste wordt opgenomen. Het oorspronkelijke eerste commando wordt de sub-query! Het commando levert direct het gewenste resultaat, zonder dat je gebruik hoeft te maken van een kladpapiertje: 28 Spoedcursus SQL met MS-Access
Naam Hoeben Tuinier Zachariassen Een ander voorbeeld is het volgende. Men wil een lijst maken met de namen van de personeelsleden die in week 21 verkooporders van meer dan 20.000 euro hebben genoteerd. Het commando is: SELECT naam WHERE mednr IN (SELECT mednr FROM verkooporders WHERE weeknr=21 AND orderbedrag>20000); Naam Zweers De sub-query levert een verzameling van slechts 1 personeelslid dat aan de twee criteria (weeknummer = 21 en orderbedrag>20000) voldoet. Vervolgens wordt de naam van deze medewerker getoond. Een belangrijke afspraak bij het gebruik van de sub-query is: Achter de SELECT van de sub-query mag slechts één kolomnaam worden opgenomen. Dit is dezelfde kolomnaam als voor de IN-operator is opgenomen. De voorgaande query voldoet aan deze regel: achter de SELECT van de sub-query staat mednr. Ook voor de IN is deze kolomnaam opgenomen. Via mednr wordt in dit voorbeeld een relatie gelegd tussen de tabellen MEDEWERKERS en VERKOOPORDERS. Opdracht Open het queryvenster, kies voor ontwerpweergave, sluit vervolgens het venster tabel weergeven en kies met de knop query-weergave voor SQL-weergave. Geef het volgende SQL-commando: SELECT klantnr, naam FROM klanten WHERE klantnr IN (SELECT klantnr FROM verkooporders WHERE weeknr=21); Klantnr Naam 100014 Leonardo P.P. 100024 Broeckhove T.H. 100038 Adams M.A. Spoedcursus SQL met MS-Access 29
3.3 De sub-query, unieke mogelijkheden De vragen die in de vorige paragraaf met een suq-query werden opgelost hadden ook heel goed met een JOIN kunnen worden gemaakt. Bij veel queries waarbij gezocht wordt in verschillende tabellen kun je kiezen van welke techniek je gebruik wenst te maken: de join of de sub-query. Voor een tweetal typen vraagstukken geldt dat er geen gebruik kan worden gemaakt van een join, maar dat gebruikgemaakt móét worden van een sub-query. Het eerste soort vraagstuk bevat een functie, het tweede soort vraagstuk bevat een ontkenning, een negatie. Neem bijvoorbeeld de vraag: Wie verdient het hoogste salaris? Deze wordt beantwoord met het commando: SELECT naam, basissalaris WHERE basissalaris IN (SELECT MAX(basissalaris) ); Naam Basissalaris Winkelman 89.000,00 In voorgaande query wordt in een commando tweemaal dezelfde tabel geraadpleegd. Allereerst wordt de laatste query geëvalueerd waaruit blijkt dat het hoogste salaris voorkomt in de tabel Medewerkers: 89000. Dit getal wordt als tussenresultaat opgeslagen. Vervolgens wordt de eerste query door Access afgehandeld: welke medewerker(s) verdienen evenveel als het tussenresultaat (89000)? Opdrachten 3.6 Welk product is het goedkoopst? 3.7 Welke medewerker is het langst in dienst? 3.8 Welke factuur is het laatst betaald? 3.9 Welke klant heeft de order geplaatst met het hoogste orderbedrag? Geef klantnaam en orderbedrag. De tweede soort vraagstukken waarbij een sub-query gebruikt moet worden is te herkennen aan de ontkenning in de vraagstelling (ontkenning wordt ook wel negatie genoemd). Een voorbeeld van een dergelijke vraag is: Welke klanten hebben in 2005 geen orders geplaatst? Het commando dat antwoord op de vraag geeft ziet er als volgt uit: SELECT naam, adres, plaats FROM klanten WHERE klantnr NOT IN (SELECT klantnr FROM verkooporders WHERE orderdat BETWEEN #01/01/2004# AND #31/12/2004#); Allereerst onderzoekt Access het tweede gedeelte van de query en maakt een tussenresultaat in de vorm van een verzameling van alle klantnummers die voorkomen in de verkooporders van 2004. Vervolgens zoekt Access naar de adresgegevens van de klanten van wie het klantnummer NIET voorkomt in het tussenresultaat. 30 Spoedcursus SQL met MS-Access
Opdrachten 3.10 Welke medewerkers van de Verkoopafdeling hebben in januari 2006 geen orders geboekt? 3.11 Van welke producten is afgelopen jaren niets verkocht? Spoedcursus SQL met MS-Access 31
4 Groeperen Een belangrijke mogelijkheid binnen SQL is om gegevens die op een of andere wijze bij elkaar horen te clusteren. De clusters kunnen dan gebruikt worden om er operaties op los te laten, zoals sommeren of het gemiddelde nemen. De uitkomst zal alleen voor het cluster gelden. Een andere cluster zal een andere uitkomst van de functie opleveren. Eerst zal besproken worden wat een cluster of groep is. 4.1 Het definiëren van groepen: GROUP BY Stel dat je een overzicht wil maken van het aantal klanten in elke plaats. We kunnen deze informatie krijgen door achtereenvolgens queries te maken als: SELECT COUNT(*) FROM klanten WHERE plaats = Loosdrecht ; SELECT COUNT(*) FROM klanten WHERE plaats = Weesp ; SELECT COUNT(*) FROM klanten WHERE plaats = Yerseke ; Het is duidelijk dat het intypen van een commando voor elke plaats een zeer omslachtige methode is. Met de GROUP BY toevoeging is het binnen SQL mogelijk dit soort overzichten met een commando te genereren. De toevoeging GROUP BY groepeert individuele rijen tot verzamelingen van rijen: de groepen. Om de hiervoor genoemde vraag te beantwoorden is een GROUP BY-toevoeging nodig met daarnaast een COUNT-functie in de eerste regel van het commando. Het SQL-commando wordt: SELECT plaats, COUNT(*) FROM klanten GROUP BY plaats; 32 Spoedcursus SQL met MS-Access
Plaats Expr1001 Almelo 1 Castricum 1 Elspeet 1 Landsmeer 3 Loosdrecht 2 Mijdrecht 2 Nieuw-Vennep 2 Oirschot 1 Petten 1 Rolde 1 Sappemeer 17 St. Pancras 2 Vierhuizen 1 Weesp 1 Winschoten 1 Yerseke 1 Door de GROUP BY wordt gegroepeerd naar plaats. Per plaats wordt het aantal klanten geteld en met de plaats weergegeven in de lijst. In het volgende voorbeeld wordt het aantal medewerkers per afdeling geteld: SELECT afdeling, COUNT(*) GROUP BY afdeling; Afdeling Expr1001 Assemblage 1 Financiën 1 Inkoop 1 Magazijn 1 Verkoop 9 Indien met de GROUP BY groepen worden gedefinieerd moet altijd een van de volgende functies worden gebruikt: COUNT(*) tellen SUM optellen AVG gemiddelde bepalen MAX maximum bepalen MIN minimum bepalen In het volgende voorbeeld wordt per afdeling het totaal van de loonkosten berekend. De SUM-expressie is nodig omdat de salarissen van de medewerkers gegroepeerd per afdeling bij elkaar worden opgeteld: SELECT afdeling, SUM(basissalaris) GROUP BY afdeling; Spoedcursus SQL met MS-Access 33
Afdeling Expr1001 Assemblage 41.000,00 Financiën 81.000,00 Inkoop 45.000,00 Magazijn 89.000,00 Verkoop 436.000,00 Het verschil tussen COUNT(*) en SUM blijkt goed uit het volgende voorbeeld: SELECT functie, COUNT(*), SUM(basissalaris) GROUP BY functie ORDER BY 3; Functie Expr1001 Expr1002 Inpakker 1 41.000,00 Telefonist 1 45.000,00 Administratie 1 81.000,00 Verkoper 2 86.000,00 Chef 1 89.000,00 Vertegenwoordiger 7 350.000,00 Uit voorgaand overzicht blijkt bijvoorbeeld dat er twee medewerkers werken in de Binnendienst die samen 86.000 euro verdienen. Het overzicht is gesorteerd op de derde kolom. Een belangrijke regel bij het gebruik van GROUP BY is dat de veldnamen achter de GROUP BY ook moeten voorkomen achter het SELECT-onderdeel. In voorgaand voorbeeld komt de veldnaam functie zowel achter de SELECT als achter de GROUP BY voor. 4.2 Gebruik queryvenster Bij het samenstellen van een GROUP BY kan binnen Access handig gebruikgemaakt worden van het queryvenster. Om dit te demonstreren wordt wederom de vraag gesteld wat de totale loonkosten zijn per afdeling. Allereerst wordt de tabel, bijvoorbeeld Medewerkers, toegevoegd aan het queryvenster. Druk vervolgens op de werkbalk op de knop Totalen: Hiermee wordt aangegeven dat er een GROUP BY-constructie opgebouwd gaat worden. In het queryraster komt er een regel bij onder dezelfde naam Totalen. In deze regel staat vervolgens onder elk gekozen veld de term Group By. Dit moet op de juiste wijze worden ingevuld. Het attribuut Afdeling wordt al gegroepeerd zoals in de regel Totaal te zien is. Het attribuut Basissalaris zal nog de Som-functie moeten krijgen door op de Totaalregel binnen het attribuut Basissalaris te klikken en de functie som te selecteren, zoals in figuur 4.1 te zien is. 34 Spoedcursus SQL met MS-Access
Figuur 4.1 Group By met behulp van Queryvenster Opdracht 4.1 Voer deze bewerkingen uit zodat figuur 4.1 ontstaat. Het bijbehorende resultaat wordt zichtbaar door te schakelen naar gegevensbladweergave: Afdeling SomVanbasissalaris Assemblage 41.000,00 Financiën 81.000,00 Inkoop 45.000,00 Magazijn 89.000,00 Verkoop 436.000,00 Access vertaalt de query naar een SQL-commando dat zichtbaar wordt door met de (linker)knop queryweergave te schakelen naar SQL-weergave: SELECT medewerkers.afdeling, Sum(medewerkers.basissalaris) AS SomVanbasissalaris GROUP BY medewerkers.afdeling; In dit commando wordt ten overvloede bij elk vermeld attribuut ook de bijbehorende tabelnaam gegeven. Het gesommeerde bedrag wordt tevens opgeslagen in een variabele genaamd SomVanbasissalaris. Opdrachten 4.2 Maak een overzicht waaruit we per klant kunnen aflezen wat het aantal verkooporders is dat de diverse klanten in de eerste helft van 2002 hebben geplaatst. Toon van deze klanten de klantennummers. Noteer het SQL-commando. 4.3 Maak een lijst met twee kolommen. De eerste kolom vermeldt het klantennummer, de tweede kolom het totale orderbedrag van de verkopen aan deze klant. Sorteer het overzicht zodanig dat de beste klant bovenaan staat. Noteer het SQL-commando. 4.4 Maak een overzicht waarin per stad het aantal medewerkers wordt weergegeven. Tip: voor deze opdracht tel je het aantal medewerkers per stad. Voor het tellen gebruikt je COUNT(*). Noteer het SQL-commando. 4.5 Het bedrijf BitByBit kent rustige en drukke weken. Maak een overzicht van de totale orderbedragen per week. Sorteer het overzicht. Noteer het SQL-commando. 4.6 Maak een lijst waarop voor elk product het totaal aantal stuks staat vermeld dat van dit product werd verkocht. Gebruik het queryvenster. 4.7 Maak een lijst met twee kolommen. De eerste kolom vermeldt de naam van de klant. De tweede kolom het totale orderbedrag van de verkopen aan deze klant. Sorteer het overzicht zodanig dat de beste klant bovenaan staat. Tip: Raadpleeg twee bestanden en gebruik de JOIN. Gebruik het queryvenster. Spoedcursus SQL met MS-Access 35
4.3 Selecties op groepen: HAVING In de vorige paragraaf werd een overzicht gemaakt van het aantal klanten in elke stad. Stel nu dat een medewerker een overzicht wil maken van alle steden waar meer dan twee klanten zijn gevestigd, dan wordt het SQL-commando: SELECT plaats, COUNT(*) FROM klanten GROUP BY plaats HAVING COUNT(*)>2; Plaats Expr1 Landsmeer 3 Sappemeer 17 Met behulp van de component HAVING worden, nadat de rijen zijn gegroepeerd op plaatsnaam, alleen die plaatsen geselecteerd waar meer dan twee klanten zijn gevestigd. De HAVING-toevoeging kan alleen maar voorkomen in combinatie met een GROUP BY. 4.4 Gebruik queryvenster bij HAVING Een soortgelijke constructie kan op eenvoudige wijze worden opgebouwd via het queryvenster. Eerst wordt de juiste tabel toegevoegd. In de werkbalk wordt weer op de knop Totalen gedrukt: Het veld plaats wordt in de eerste kolom gezet, volgens figuur 4.2. Figuur 4.2 Stap 1: de Group By In de tweede kolom wordt de expressie COUNT(*) ingetypt. In de regel Totaal kies je voor Expressie. In de regel criteria wordt gekozen voor: >2. Zie figuur 4.3. Figuur 4.3 Stap 2: toevoegen Having inclusie criterium Opdrachten 4.8 Maak een overzicht van de topweken: alle weken waarin meer dan 50.000 euro aan omzet werd behaald. Noteer het SQL-commando. 4.9 Maak een overzicht van eenmalige klanten : zij die slechts één order hebben geplaatst. Toon van die klanten de klantnummers. 4.10 Maak een soortgelijk overzicht: klanten die slechts één order hebben geplaatst. Toon van die klanten de namen. 36 Spoedcursus SQL met MS-Access
4.11 Maak een overzicht van de afdelingen waar maandelijks meer dan 5.000 euro in totaal aan loonkosten wordt uitbetaald (uitgaande van het basissalaris). 4.12 Van welke producten zijn er meer dan tien stuks verkocht? Toon van deze producten het productnummer en het totaal aantal dat verkocht is. 4.13 Maak een lijst waarop de namen, de adressen en de vestigingsplaatsen staan vermeld, met daarbij het totale orderbedrag van de klanten die in totaal voor meer dan 50.000 euro aan orders hebben geplaatst. 4.14 Van welke producten zijn er in 2002 (!) meer dan vijftig stuks verkocht? Toon van dit product de omschrijving en het totale aantal verkochte producten. Spoedcursus SQL met MS-Access 37
Bijlage Database BitByBit Producten (productnr, omschrijving, prijs, voorraad, productsoort) Klanten (klantnr, naam, adres, postcode, plaats, telnr) Medewerkers (mednr, naam, adres, plaats, afdeling, functie, datumin, basissalaris, provisiep) Verkooporders (ordernr, klantnr, mednr, orderdat, weeknr, orderbedrag) Orderregels (ordernr, productnr, aantal) Facturen (factuurnr, ordernr, factuurdat, productsoort, bedrag, betaald) Betalingen (factuurnr, betaaldat, klantnr, bedrag) 38 Spoedcursus SQL met MS-Access