Last chance! 50% off DataCamp Premium
Sale ends in
In deze tutorial focus je op ANSI (American National Standards Institute) SQL die op elke database werkt, zoals Oracle, MySQL, Microsoft SQL Server, enz.! Laten we beginnen met een introductie tot SQL (Structured Query Language) en waarom een data scientist het nodig kan hebben.
In dit deel van de tutorial zie je waarom een data scientist SQL zou moeten leren. Kijk hoe SQL je helpt in je carrière als data scientist:
Hier geef ik een korte introductie en terminologie die in SQL en databases wordt gebruikt om je te helpen sneller te leren coderen! Als je al weet wat een relationele database is en wat SQL is, dan kun je doorspringen naar de code.
Een database is een georganiseerde verzameling informatie. Om databases te beheren, hebben we Data Base Management Systems (DBMS) nodig. Een DBMS is een programma dat op verzoek data in databases opslaat, ophaalt en wijzigt.
Er zijn door de tijd verschillende soorten databases geweest: hiërarchische, netwerk-, relationele databases en nu NoSQL-databases. Een relationele database is een verzameling relaties of tweedimensionale tabellen.

De volgende terminologie wordt gebruikt in RDBMS:
| Term | Beschrijving |
|---|---|
| Tabel | Een tabel is de basisopslagstructuur van een RDBMS. Een tabel slaat alle benodigde data op over iets in de echte wereld. Voorbeeld: Employees. |
| Rij of tuple | Vertegenwoordigt alle data die nodig is voor een specifieke werknemer. Elke rij in een tabel kan worden geïdentificeerd door een primaire sleutel, die dubbele rijen niet toestaat. |
| Kolom of attribuut | Verwijst meestal naar een kenmerk van een entiteit |
| Primaire sleutel | Een veld dat een rij uniek identificeert |
| Vreemde sleutel | Een vreemde sleutel is een kolom die aangeeft hoe tabellen met elkaar in verband staan. Een vreemde sleutel verwijst naar een primaire sleutel in een andere tabel. |
Je kunt meerdere tabellen aan elkaar relateren met primaire en vreemde sleutels. Elke rij in een relationele database wordt uniek geïdentificeerd door een primaire sleutel (PK). Je kunt naar een andere tabel verwijzen met een vreemde sleutel (FK). Bijvoorbeeld:

Relationele databases zijn toegankelijk via Structured Query Language of SQL. Elke database ondersteunt ANSI SQL, de standaard SQL, maar zal ook eigen syntax hebben om bepaalde bewerkingen te vergemakkelijken. In deze tutorial leer je ANSI SQL zodat je met alle databases kunt werken. ANSI SQL kan in vijf secties worden verdeeld. Ik noem ze allemaal, maar hier zijn alleen twee secties relevant: Data Retrieval en DML:
Er zijn verschillende leveranciers voor RDBMS. De meest voorkomende en meest gebruikte zijn:
Waar voer je SQL-queries uit? Dat kan zijn:
Als je inloggegevens voor een database hebt, kun je de databaseobjecten bekijken met queries of via een GUI, afhankelijk van je databaseleverancier.
Dat was het! Laten we SQL gaan leren...
Elke kolom in een database heeft een naam en een datatype en soms een gekoppelde grootte. Het is de taak van de databasedeveloper om de database te ontwerpen en te bepalen welk datatype moet worden gebruikt op basis van de vereisten en de hoeveelheid data.
Als data scientist moet je bekend zijn met de datatypen, omdat dit je helpt databasefuncties correct te gebruiken en je queries nauwkeurig te schrijven. Er is een datatype voor elk type kolom in een database, zoals iemands naam, opgeslagen tekst, getallen, een afbeelding die in de database is opgeslagen, enzovoort.
Hier worden basisdatatypen voor Oracle Server, SQL Server en MySQL Server getoond:

Voor verder lezen:
Voor alle SQL die in deze tutorial wordt gebruikt, geldt het volgende voorbeeld van een databaseschema:
Beschouw een database met twee tabellen, genaamd emp, die werknemersdata bevat, en dept, die records over afdelingen bevat.
De emp-tabel heeft werknemernummer (empno), werknemersnaam (ename), salaris (sal), commissie (comm), functienaam (job), manager-id (mgr), datum in dienst (hiredate) en afdelingsnummer (deptno). Omdat een manager ook een werknemer is en een werknemernummer heeft, is mgr een van de empno’s waarvan de job "MANAGER" is.
De dept-tabel heeft afdelingsnummer (deptno), afdelingsnaam (dname) en locatie van de afdeling (loc).

Merk op dat verschillende databases een verschillend datumformaat hebben. Hier is DD-MON-YY het standaarddatumformaat voor een Oracle-database. Het standaardformaat voor Microsoft SQL Server en MySQL is YYYY-MM-DD.
Jouw databasetabellen kunnen anders zijn, dus je hoeft alleen aan te passen aan jouw tabelnaam en attribuutnamen. In deze tutorial lees je alleen uit de database en schrijf je niet naar, werk je niet bij en maak je geen nieuwe tabellen of objecten. Geen zorgen dus over dataverlies of wijzigingen!
Informatie: Een schema is een verzameling objecten zoals tabellen, functies, procedures en views die bij een gebruiker horen
In het bovenstaande databaseschema zie je dat de emp-tabel zes attributen heeft voor de entiteit Employee. Tabel dept heeft drie attributen voor de entiteit Department.
Een SELECT-instructie haalt informatie uit de database. Met een SELECT-instructie kun je het volgende doen:
1. Projectie: je kunt in SQL de projectiemogelijkheid gebruiken om de kolommen in een tabel te kiezen die je door je query wil laten teruggeven. Je kunt zo weinig of zoveel kolommen kiezen als je nodig hebt.
2. Selectie: je kunt in SQL de selectiemogelijkheid gebruiken om de rijen in een tabel te kiezen die je wil laten teruggeven door een query.
Je kunt verschillende criteria gebruiken om de rijen te beperken die je ziet.
3. Joinen: je kunt in SQL de join-mogelijkheid gebruiken om data samen te brengen die in verschillende tabellen is opgeslagen door een link ertussen te maken.
De basis-SELECT-instructie laat je specificeren welke kolommen je uit welke tabel wilt. De SELECT-clausule specificeert kolommen en expressies en de FROM-clausule specificeert uit welke tabel je data haalt.
Bijvoorbeeld: Wat zijn de namen van alle werknemers en wat zijn hun functies: SELECT ename, job FROM employee; De bovenstaande SQL-query geeft je de volgende output op basis van het hierboven besproken databaseschema:
| ename | job |
|---|---|
| A | Salesman |
| B | Manager |
| C | Manager |
Om alle attributen en alle rijen uit een tabel te selecteren, gebruik je de *-operator:
SELECT *
FROM employee;
The output will be:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
Een paar tips voor het schrijven van SQL-instructies:
- SQL-instructies zijn niet hoofdlettergevoelig
- Schrijf clausules op aparte regels voor de leesbaarheid
- Je kunt een SQL-instructie op één of meerdere regels schrijven
Je kunt ook een expressie maken met de operatoren +, -, /, * op datum- en numerieke data om gewenste resultaten te genereren. Bijvoorbeeld, je moet 20% van het salaris van alle werknemers bepalen. De query is als volgt:
SELECT ename, sal*(20/100)
FROM employee;
Output:
ENAME SAL*(20/100)
---------- ------------
SMITH 160
ALLEN 320
WARD 250
JONES 595
BLAKE 570
Informatie:
- Haakjes worden gebruikt om de expressie te verduidelijken
- Deling en vermenigvuldiging hebben voorrang boven optelling en aftrekking
- Als dezelfde prioriteit voorkomt, wordt de expressie van links naar rechts geëvalueerd
NULL-waarden worden in databases anders behandeld. Een NULL-waarde impliceert dat een waarde onbekend is. Elke bewerking met NULL resulteert in NULL. Verschillende databases hebben verschillende functies om null te behandelen. Er is een gemeenschappelijke functie die in MySQL, Microsoft SQL Server en Oracle wordt gebruikt om NULL’s te behandelen.
SELECT ename, sal+COALESCE(comm,0)
FROM employee;
Output:
ENAME SAL+COALESCE(COMM,0)
---------- --------------------
SMITH 800
ALLEN 1900
WARD 1750
JONES 2975
BLAKE 2850
Je ziet hierboven dat de kolomnaam hetzelfde is als het databaseveld of de expressie die je selecteert. Soms wil je bij het genereren van rapporten je eigen namen aan de koppen geven. Dit kan met aliassen.
SELECT ename AS "Emp Name", sal*(20/100) as "20% of Salary"
FROM employee;
Output:
Emp Name 20% of Salary
---------- ------------
SMITH 160
ALLEN 320
WARD 250
JONES 595
BLAKE 570
Als je een alias gebruikt met spaties erin, moet je dubbele aanhalingstekens gebruiken. Anders is dat niet nodig na AS. Soms kun je het sleutelwoord AS ook weglaten.
Je kunt je uitvoer opmaken door te concateren. Je kunt je eigen tekst aan de uitvoer toevoegen met de functie CONCAT of operatoren zoals || of +, afhankelijk van de databaseleverancier:
Oracle: SELECT '20% of salary of '||ename||' is '||sal*(20/100) as "20% of salary" FROM employee;
SELECT CONCAT(CONCAT('20% of salary of',ename),CONCAT(' is ',sal(20/100))) as "20% of salary" FROM employee; MySQL en Microsoft SQL Server: SELECT CONCAT('20% of salary of ',ename,' is ',sal(20/100)) as "20% of salary" FROM employee; Alle geven dezelfde output:
20% of salary
-----------------------------------------------------------------------
20% of salary of SMITH is 160
20% of salary of ALLEN is 320
20% of salary of WARD is 250
20% of salary of JONES is 595
20% of salary of BLAKE is 570
SELECT deptno
FROM employee;
Above query will result in:
DEPTNO
----------
20
30
30
20
30
Hier herhalen deptno 20 en 30 zich. Je kunt zulke rijen verwijderen met het sleutelwoord DISTINCT in de SELECT-clausule.
SELECT distinct ename, deptno, job
FROM employee;
DEPTNO
----------
30
20
De WHERE-clausule wordt gebruikt om data op een bepaalde voorwaarde te filteren.
Zoek alle werknemers met job CLERK:
SELECT ename, job
FROM employee
WHERE job='CLERK';
ENAME JOB
---------- ---------
SMITH CLERK
Je kunt je resultaten met verschillende voorwaarden filteren. Hiervoor worden operatoren, conditionele symbolen en specifieke sleutelwoorden gebruikt:

Gebruik van =, <>, !=, >=, <=, >, < is eenvoudig, zoals te zien is in de bovenstaande query die = gebruikt.
AND & OR-syntax: SELECT column1, column2,.. FROM table_name WHERE condition1 AND condition2 AND condition 3...;
SELECT column1, column2,.. FROM table_name WHERE condition1 OR condition2 OR condition 3...; Zoek namen van werknemers wiens job MANAGER is en die bij afdeling 30 horen:
SELECT ename
FROM employee
WHERE job='MANAGER' AND deptno=30;
ENAME
----------
BLAKE
SELECT ename
FROM employee
WHERE job='MANAGER' OR deptno=30;
ENAME
----------
ALLEN
WARD
JONES
BLAKE
NOT-syntax: SELECT column1, column2, ... FROM table_name WHERE NOT condition; Zoek alle werknemers wiens job niet SALESMAN is:
SELECT ename, job
from employee
WHERE NOT job='SALESMAN';
ENAME JOB
---------- ---------
SMITH CLERK
JONES MANAGER
BLAKE MANAGER
Je kunt complexe voorwaarden maken met AND, OR en NOT samen. De prioriteit is:
Zoek alle werknemers wiens job niet CLERK is en die bij afdeling 20 horen:
SELECT ename, job
from employee
WHERE NOT job='SALESMAN' AND sal>800;
ENAME JOB
---------- ---------
JONES MANAGER
BLAKE MANAGER
Hier werd eerst NOT uitgevoerd en daarna AND geëvalueerd.
Andere handige conditionele operatoren staan hieronder:
BETWEEN...AND:
SELECT *
FROM employee
WHERE sal BETWEEN 1000 AND 2000;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
LIKE:
LIKE gebruikt twee wildcards: procentteken % en underscore _ om het aantal tekens in het patroon weer te geven.
Patronen zijn hoofdlettergevoelig.
Haal de namen op van alle werknemers wier naam begint met 'B':
SELECT *
FROM employee
WHERE ename LIKE 'B%';
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
Haal de namen op van alle werknemers wier naam begint met 'A' en een 'E' op een willekeurige positie na 'A' bevat:
SELECT *
FROM employee
WHERE ename LIKE 'A%E%';
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
IN(value1,value2, value3,..):
De functie IN() kan één, twee of meerdere waarden aannemen en laat je in de WHERE-clausule een kolom laten overeenkomen met de opgegeven waarden tussen haakjes:
SELECT ename, job, hiredate
FROM employee
WHERE job IN ('CLERK','SALESMAN');
ENAME JOB HIREDATE
---------- --------- ---------
SMITH CLERK 17-DEC-80
ALLEN SALESMAN 20-FEB-81
WARD SALESMAN 22-FEB-81
Je kunt ook een SELECT-instructie in IN() gebruiken die enkele waarden teruggeeft. Bijvoorbeeld:
SELECT ename, job, hiredate
FROM employee
WHERE deptno IN (select deptno FROM department WHERE loc='CHICAGO');
ENAME JOB HIREDATE
---------- --------- ---------
ALLEN SALESMAN 20-FEB-81
WARD SALESMAN 22-FEB-81
BLAKE MANAGER 01-MAY-81
De SELECT-instructie in IN() wordt ook wel een subquery genoemd. Later in deze tutorial meer over subqueries!
IS NULL:
IS NULL wordt gebruikt om te controleren op NULL-waarden in een bepaald attribuut. Bijvoorbeeld, zoek alle werknemers die geen commissie hebben:
SELECT ename, job, sal
FROM employee
WHERE comm IS NULL;
ENAME JOB SAL
---------- --------- ----------
SMITH CLERK 800
JONES MANAGER 2975
BLAKE MANAGER 2850
Als je de namen wilt ophalen van werknemers die wel commissie hebben verdiend, gebruik je IS NOT NULL:
SELECT ename, job, sal, comm
FROM employee
WHERE comm IS NOT NULL;
ENAME JOB SAL COMM
---------- --------- ---------- ----------
ALLEN SALESMAN 1600 300
WARD SALESMAN 1250 500
Om resultaten te filteren met datumkolommen moet je het standaarddatumformaat gebruiken. Als een ander formaat nodig is, moeten datumfuncties worden toegepast, wat je later in deze tutorial ziet. Zoek alle werknemers die zijn aangenomen na 21 februari 1981:
(Hier wordt het standaard Oracle-datumformaat gebruikt)
SELECT ename, job, sal, comm
FROM employee
WHERE hiredate>'21-FEB-81';
ENAME JOB SAL COMM
---------- --------- ---------- ----------
WARD SALESMAN 1250 500
JONES MANAGER 2975
BLAKE MANAGER 2850
Complexe voorwaardelijke expressies kunnen worden gemaakt met een combinatie van alle bovenstaande operatoren, maar je moet voorzichtig zijn met prioriteit. Prioriteit is de volgorde waarin operatoren worden geëvalueerd. Hieronder vind je prioriteitsregels voor verschillende databases:
Er zijn twee nuttige functies: ANY() en ALL() die in voorwaarden kunnen worden gebruikt. Bijvoorbeeld:
SELECT ename, job, sal, comm FROM employee WHERE deptno=ANY(SELECT deptno from dept WHERE loc='NEW YORK');
SELECT ename, job, sal, comm FROM employee WHERE deptno=ALL(SELECT deptno from dept WHERE dname='SALES');
Let op het gebruik van subqueries in de bovenstaande voorbeelden. Je leert later meer over subqueries.
Je kunt je resultaten oplopend (ASC) of aflopend (DESC) sorteren op elk attribuut of meerdere attributen van de tabel. Je kunt ook sorteren op aliassen die je in de SELECT-clausule specificeert:
SELECT ename, job, sal, comm
FROM employee
WHERE hiredate>'21-FEB-81'
ORDER BY sal desc;
ENAME JOB SAL COMM
---------- --------- ---------- ----------
JONES MANAGER 2975
BLAKE MANAGER 2850
WARD SALESMAN 1250 500
Opmerking: Standaard is de volgorde oplopend, aangeduid met ASC, en hoef je ASC niet te specificeren.
SELECT ename, job, sal, comm
FROM employee
WHERE hiredate>'21-FEB-81'
ORDER BY sal;
ENAME JOB SAL COMM
---------- --------- ---------- ----------
WARD SALESMAN 1250 500
BLAKE MANAGER 2850
JONES MANAGER 2975
Je kunt meerdere kolommen in de ORDER BY-clausule specificeren, die in de opgegeven volgorde worden uitgevoerd. Sorteer bijvoorbeeld werknemers eerst op hun deptno oplopend en daarna de namen aflopend:
SELECT ename, job, sal, comm, deptno
FROM employee
WHERE hiredate>'21-FEB-81'
ORDER BY deptno ASC, ename DESC;
ENAME JOB SAL COMM DEPTNO
---------- --------- ---------- ---------- ----------
JONES MANAGER 2975 20
WARD SALESMAN 1250 500 30
BLAKE MANAGER 2850 30
Er zijn talloze functies in alle RDBMS’en die je helpen bij algemene taken, zoals de lengte van een string bepalen, strings samenvoegen, opmaakfuncties, wiskundige functies, enz. Er zijn twee soorten rijfuncties in SQL:
Single-rowfuncties:
Deze functies worden op elke rij toegepast en geven per rij resultaat terug. CONCAT() is een single-rowfunctie voor tekenmanipulatie. Deze kunnen worden gebruikt in SELECT-, WHERE- en ORDER BY-clausules. Er zijn single-rowfuncties voor het volgende in alle RDBMS:
Verschillende databases hebben verschillende functienamen voor dezelfde functionaliteit. Hier vertel ik je gemeenschappelijke, nuttige functies in Microsoft SQL Server, Oracle en MySQL. Sommige hiervan heb je hierboven al gezien. Aan het einde van deze sectie vind je links naar een complete lijst met functies van deze leveranciers voor verdere oefening.
Laten we elke categorie doornemen:
LOWER(): Zet een string om naar kleine letters.
SELECT lower(ename) as ename
FROM employee;
ENAME
----------
smith
allen
ward
jones
blake
UPPER(): Zet een string om naar hoofdletters.
SELECT upper(ename) as ename
FROM employee;
ENAME
----------
SMITH
ALLEN
WARD
JONES
BLAKE
SUBSTR()[Oracle, MySQL]: Geeft een substring terug zoals opgegeven SUBSTR(string, start-positie, lengte)
SUBSTRING()[SQL Server]: Geeft een substring terug zoals opgegeven SUBSTRING(string, start-positie, lengte).
SELECT SUBSTR(ename,2,3) as substr_ename FROM employee;
Vervang voor SQL Server alleen de functienaam door SUBSTRING.
SUBSTR_ENAME ------------ MIT LLE ARD ONE LAK
LENGTH()[Oracle, MySQL]: Geeft de lengte van de string tussen haakjes terug
LEN()[SQL Server]: Geeft de lengte van de string tussen haakjes terug
SELECT LENGTH(ename) as len_ename FROM employee;
Vervang voor SQL Server alleen de functienaam door LEN.
LEN_ENAME
----------
5
5
4
5
5
Functies zoals opvullen van een string links of rechts, vervangen, enz. verschillen in syntax tussen databases. Lijsten met teken- en stringfuncties voor de drie leveranciersdatabases:
| Functienaam | Functie |
|---|---|
| ROUND(m,n): | Rondt de waarde m af op n decimalen. |
| ABS(m,n): | Geeft de absolute waarde van een getal terug |
| FLOOR(n): | FLOOR geeft het grootste geheel getal terug dat gelijk is aan of kleiner is dan n. |
| MOD(m,n): | Geeft de rest terug van de deling van m door n (niet beschikbaar in SQL Server, maar gebruikt %-operator: 35 % 6) |
Oracle:
SELECT ROUND(45.926,2),MOD(11,5),FLOOR(34.4),ABS(-24) from dual;
OUTPUT:
ROUND(45.926,2) MOD(11,5) FLOOR(34.4) ABS(-24)
--------------- ---------- ----------- ----------
45.93 1 34 24
MySQL:
SELECT ROUND(45.926,2),MOD(11,5),FLOOR(34.4),ABS(-24);
SQL Server:
SELECT ROUND(45.926,2) as round,11%5 as mod, FLOOR(34.4) as floor,ABS(-24) as abs;
Lijsten met numerieke functies voor de drie leveranciersdatabases:
Conversiefuncties worden gebruikt om het ene datatype naar het andere om te zetten. Conversiefuncties verschillen per server. Hier geef ik je een voorbeeld van een Oracle-serverquery die de functie to_char gebruikt. Dit helpt je te begrijpen hoe je conversiefuncties kunt gebruiken om de uitvoer aan te passen. Het standaarddatumformaat van Oracle is DD-MON-YY
SELECT ename, to_char(hiredate,'DD, MONTH YYYY') as Hiredate, to_char(hiredate,'DY') as Day
from employee;
ENAME Hiredate DAY
---------- -------------------------------------------- ------------
SMITH 17,DECEMBER 1980 WED
ALLEN 20,FEBRUARY 1981 FRI
WARD 22,FEBRUARY 1981 SUN
JONES 02,APRIL 1981 THU
BLAKE 01,MAY 1981 FRI
Er zijn veel conversiefuncties voor elke databaseserver. Voor verdere verdieping en verkenning vind je hieronder links naar conversiefuncties van verschillende databaseservers:
Datum- en tijdfuncties laten je de datum manipuleren door dagen toe te voegen, maanden tussen twee datums te berekenen, enz. Zulke functies zijn nuttig bij het genereren van rapporten. Datumfuncties verschillen ook per database. Een functie kan dezelfde functionaliteit hebben maar een andere naam in een andere database. Hier kijk je naar een paar voorbeelden en daarna geef ik je links naar de datumfuncties van de meest gebruikte databases: Oracle, SQL Server en MySQL. Probeer deze voorbeelden gerust op jouw databaseserver!

Groeperingsfuncties of multirijfuncties worden toegepast op groepen en geven één resultaat per groep. Je hebt groepsfuncties nodig wanneer je zaken wilt uitzoeken zoals totale verkoop per kwartaal, de gemiddelde prijs van een product over een periode, de hoogste investering die je bedrijf deze maand heeft ontvangen, enzovoort.
De GROUP BY-clausule wordt gebruikt om resultaten te groeperen en wordt vaak gebruikt met functies als COUNT, MAX, MIN, AVG en SUM. De syntax van GROUP BY is:
SELECT column_name(s) FROM table_name WHERE condition GROUP BY column_name(s) HAVING condition ORDER BY column_name(s);
Je moet een paar punten in gedachten houden voor de GROUP BY-clausule:
COUNT is een groepsfunctie die het aantal rijen telt volgens een voorwaarde of zonder voorwaarde. De COUNT-functie negeert null-waarden.
Tel alle werknemers waarvan de naam met 'A' begint:
SELECT count(ename)
FROM employee
WHERE ename LIKE 'A%';
Output:
COUNT(ENAME)
------------
1
Vind het totale salaris, gemiddelde salaris, minimale salaris en maximale salaris in de tabel employee:
SELECT sum(sal) as "TOTAL SAL", avg(sal) as "AVG SAL", min(sal) as "MIN SAL", max(sal) as "MAX SAL"
FROM employee;
TOTAL SAL AVG SAL MIN SAL MAX SAL
---------- ---------- ---------- ----------
9475 1895 800 2975
Je kunt bovenstaande resultaat ook per afdeling groeperen:
SELECT sum(sal) as "TOTAL SAL", avg(sal) as "AVG SAL", min(sal) as "MIN SAL", max(sal) as "MAX SAL", deptno
FROM employee
GROUP BY deptno;
TOTAL SAL AVG SAL MIN SAL MAX SAL DEPTNO
---------- ---------- ---------- ---------- ----------
5700 1900 1250 2850 30
3775 1887.5 800 2975 20
Je kunt ook variantie en standaarddeviatie van waarden berekenen met de volgende functies:
| Voor Oracle en MySQL | MS SQL Server |
|---|---|
| SELECT STDDEV(column_name) FROM table_name; | SELECT STDEV(column_name) FROM table_name; |
| SELECT VARIANCE(column_name) FROM table_name; | SELECT VAR(column_name) FROM table_name; |
Je kunt resultaten op meer dan één kolom groeperen.
Vind de som van salarissen per job binnen elke afdeling:
SELECT sum(sal) as "TOTAL SAL", deptno, job
FROM employee
GROUP BY deptno, job;
TOTAL SAL DEPTNO JOB
---------- ---------- ---------
800 20 CLERK
2850 30 SALESMAN
2975 20 MANAGER
2850 30 MANAGER
Je kunt groepsresultaten beperken met de HAVING-clausule. Die wordt alleen gebruikt voor groepsvoorwaarden.
Opmerking: Gebruik geen WHERE om voorwaarden op groepsfuncties toe te passen.
SELECT sum(sal) as "TOTAL SAL", deptno, job
FROM employee
GROUP BY deptno, job
HAVING sum(sal)>1000
ORDER BY sum(sal);
TOTAL SAL DEPTNO JOB
---------- ---------- ---------
2850 30 SALESMAN
2850 30 MANAGER
2975 20 MANAGER
In deze sectie worden de volgende joins besproken:
Je zult rapporten moeten tonen die data uit meerdere tabellen halen. Zie het onderstaande voorbeeld:

Om een rapport als hierboven te genereren, moet je de employee- en department-tabel koppelen en data uit beide ophalen. Hiervoor worden joins in SQL gebruikt.
Cartesisch product/Cross join:
Het cartesisch product ontstaat wanneer elke tuple van relatie R een combinatie maakt met elke tuple in relatie S.

De cartesisch-productbewerking, ook wel Cross Join genoemd, vermenigvuldigt twee tabellen om een relatie te vormen die bestaat uit alle mogelijke paren tuples uit twee tabellen. Als de ene relatie, R, I tuples heeft met M attributen en de andere relatie, S, J tuples met N attributen, dan heeft het cartesisch product IxJ tuples met M+N attributen. Een cartesisch product kan ook worden gevormd met de SQL-conforme CROSS JOIN.
SELECT empno, ename, dname
FROM employee, department;
OR
SELECT empno, ename, dname
FROM employee CROSS JOIN department;
EMPNO ENAME DNAME
---------- ---------- --------------
7369 SMITH ACCOUNTING
7499 ALLEN ACCOUNTING
7521 WARD ACCOUNTING
7566 JONES ACCOUNTING
7698 BLAKE ACCOUNTING
7369 SMITH RESEARCH
7499 ALLEN RESEARCH
7521 WARD RESEARCH
7566 JONES RESEARCH
7698 BLAKE RESEARCH
7369 SMITH SALES
EMPNO ENAME DNAME
---------- ---------- --------------
7499 ALLEN SALES
7521 WARD SALES
7566 JONES SALES
7698 BLAKE SALES
15 rijen geselecteerd.
Omdat de employee-tabel 5 tuples bevat en department 3 tuples, heeft het cartesisch product 5x3=15 rijen. Een cartesisch product wordt gegenereerd wanneer:
Wanneer data uit twee of meer tabellen nodig is, wordt een join-voorwaarde gemaakt met de gemeenschappelijke attributen die de betrokken tabellen koppelen. Dit zijn meestal de primaire sleutel en de vreemde sleutel.
Cartesische producten worden gebruikt om grote hoeveelheden data te simuleren voor testdoeleinden.
*Inner join/Equijoin:
Inner join of equijoin (term die door Oracle-ontwikkelaars wordt gebruikt) gebruikt relaties tussen primaire en vreemde sleutels om twee of meer tabellen te joinen:
SELECT ename, dname
FROM employee e,department d
WHERE e.deptno=d.deptno;
OR
SELECT ename, dname
FROM employee e
JOIN department d
ON e.deptno=d.deptno;
ENAME DNAME
---------- --------------
SMITH RESEARCH
ALLEN SALES
WARD SALES
JONES RESEARCH
BLAKE SALES
In de bovenstaande query is deptno de primaire sleutel in de department-tabel en de vreemde sleutel in de employee-tabel. Je kunt extra voorwaarden toevoegen met logische operatoren zoals hierboven besproken.
Punten om te onthouden bij JOINS:
- Als dezelfde kolomnaam in meer dan één tabel voorkomt, moet de kolomnaam worden voorzien van de tabelnaam. Het is sowieso een goede gewoonte voor de duidelijkheid.
- Om n tabellen te joinen, heb je minimaal n-1 join-voorwaarden nodig. Bijvoorbeeld, om vier tabellen te joinen, zijn minimaal drie joins nodig.
Tabelaliassen: Tabelaliassen worden gebruikt, zoals in FROM employee e, department d waar e en d tabelaliassen zijn, om het de database-engine makkelijker te maken te identificeren uit welke tabel de kolom komt, vooral wanneer dezelfde kolommen in meer dan één betrokken tabel aanwezig zijn, omdat je anders een fout voor onduidelijke kolom krijgt. En het bespaart tijd omdat je niet steeds lange tafelnamen hoeft te typen.
Je kunt ook nonequi-joins maken die tabellen joinen op basis van andere voorwaarden dan gelijkheid. Beschouw een andere tabel, salgrade, die informatie bevat over de graad van een werknemer op basis van salaris:

Je wilt voor elke werknemer de graad op basis van salaris bepalen, waarbij de graden zijn opgeslagen in salgrade en het salaris in employee:
SELECT e.ename, e.sal, s.grade
FROM employee e, salgrade s
WHERE e.sal between s.losal AND s.hisal;
ENAME SAL GRADE
---------- ---------- ----------
JONES 2975 4
BLAKE 2850 4
ALLEN 1600 3
WARD 1250 2
SMITH 800 1
Voorbeeld: Je wordt gevraagd de namen van werknemers, hun salaris, graad en afdelingsnaam te geven. Omdat salaris is opgeslagen in employee, graden in salgrade en de afdelingsnaam in department, moet je drie tabellen joinen:
SELECT e.ename, e.sal, d.dname, s.grade FROM employee e, department d, salgrade s WHERE e.deptno=d.deptno AND e.sal BETWEEN s.losal AND s.hisal; Output: ENAME SAL DNAME GRADE ---------- ---------- -------------- ---------- JONES 2975 RESEARCH 4 BLAKE 2850 SALES 4 ALLEN 1600 SALES 3 WARD 1250 SALES 2 SMITH 800 RESEARCH 1
In dit voorbeeld zijn drie tabellen betrokken en twee join-voorwaarden, waarvan één een nonequi-join is.
Natural join:
Natural joins laten databases tabellen automatisch joinen door kolommen met dezelfde naam te matchen. Als kolommen met dezelfde naam overeenkomen maar verschillende datatypen hebben, dan treedt een fout op.
Syntax: SELECT FROM table1 NATURAL JOIN table2; SELECT FROM employee NATURAL JOIN department; Omdat natural join zelf de overeenkomende kolom vindt, kan het meer dan één match vinden met dezelfde naam maar een verschillend datatype, wat een fout kan opleveren. Dus wordt de USING-clausule gebruikt om kolommen te specificeren waarop een equijoin moet worden gemaakt.
Opmerking: NATURAL JOIN en USING zijn twee verschillende clausules en worden los van elkaar gebruikt. De één kan niet in aanwezigheid van de ander worden gebruikt; ze sluiten elkaar uit.
SELECT e.ename, d.dname, e.sal FROM employee e JOIN department d USING (deptno) WHERE deptno=20; output: ENAME DNAME SAL ---------- -------------- ---------- SMITH RESEARCH 800 JONES RESEARCH 2975
Kolommen in de USING-clausule kunnen nergens in de SQL-instructie de tabelnaam of tabelprefixen gebruiken. Bijvoorbeeld, het volgende is onjuist:
SELECT e.ename, d.dname, e.sal FROM employee e JOIN department d USING (d.deptno) WHERE d.deptno=20;
d.deptno is onjuist. Alleen deptno moet worden gebruikt. Outer joins:
Er zijn drie outer joins:
Laten we ze één voor één bekijken:
SELECT e.ename, s.grade FROM salgrade s LEFT OUTER JOIN employee e ON e.sal BETWEEN s.losal AND s.hisal; Output: ENAME DEPTNO DNAME ---------- ---------- -------------- SMITH 20 RESEARCH JONES 20 RESEARCH ALLEN 30 SALES WARD 30 SALES BLAKE 30 SALES.sal BETWEEN s.losal AND s.hisal; Output: ENAME DEPTNO DNAME ---------- ---------- -------------- SMITH 20 RESEARCH JONES 20 RESEARCH ALLEN 30 SALES WARD 30 SALES BLAKE 30 SALESSELECT e.ename, d.deptno, d.dname
FROM employee e RIGHT OUTER JOIN department d
ON e.deptno=d.deptno;
output:
ENAME DEPTNO DNAME
---------- ---------- --------------
SMITH 20 RESEARCH
ALLEN 30 SALES
WARD 30 SALES
JONES 20 RESEARCH
BLAKE 30 SALES
10 ACCOUNTINGSELECT e.ename, d.deptno, d.dname
FROM employee e FULL OUTER JOIN department d
ON e.deptno=d.deptno;
Output:
ENAME DEPTNO DNAME
---------- ---------- --------------
SMITH 20 RESEARCH
ALLEN 30 SALES
WARD 30 SALES
JONES 20 RESEARCH
BLAKE 30 SALES
10 ACCOUNTING
De department-tabel had één niet-overeenkomende rij voor deptno 10, en er werd geen niet-overeenkomende rij voor de employee-tabel gevonden. Evenzo heeft salgrade één niet-overeenkomende rij voor graad 5.
Self join:
Er zijn situaties waarin je een tabel met zichzelf wilt joinen. Bijvoorbeeld, de employee-tabel bevat informatie over alle werknemers, inclusief managers (zie de employee-tabel hierboven). Als je de werknemers en hun managers wilt vinden, moet je een tabel met zichzelf joinen. Self-joins worden als volgt gemaakt:
SELECT e.ename as Employee, m.ename as Manager
FROM employee e, employee m
WHERE e.mgr=m.empno;
EMPLOYEE MANAGER
---------- ----------
ALLEN BLAKE
WARD BLAKE
Een subquery is een query binnen een query. Een subquery is handig om grote queries op te delen. Subqueries kunnen worden genest en kunnen worden gebruikt in de volgende SQL-clausules:
Neem een voorbeeld: je wordt gevraagd een werknemer te vinden wiens salaris hoger is dan dat van een andere werknemer, in dit geval James. Hoe pak je dit aan? Deze query kan worden opgesplitst in:
Dit kan met een subquery. De subquery (inner query) wordt één keer uitgevoerd vóór de hoofd- (outer) query.
SELECT empno, ename FROM employee WHERE sal>(SELECT sal from employee where ename='JAMES');
Typen subqueries:
Single-row subquery: query die slechts één rij teruggeeft uit een innerlijke SELECT-instructie.
Multiple-row subquery: query die meer dan één rij teruggeeft uit een innerlijke SELECT-instructie.
Punten om te onthouden:
- Zet subqueries tussen haakjes.
- Plaats subqueries rechts van de vergelijkingsoperator.
- Gebruik enkelrij-operatoren (>, <, >=, <=, <>) met single-row subqueries.
- Gebruik meerrij-operatoren (IN, ANY, ALL) met multiple-row subqueries.
Single-row subquery:
Je wordt gevraagd de namen te vinden van werknemers wier functietitel hetzelfde is als empno 7521
SELECT ename, job
FROM employee
WHERE job=(SELECT job FROM employee WHERE empno=7521);
ENAME JOB
---------- ---------
ALLEN SALESMAN
WARD SALESMAN
Selecteer het maximale salaris van afdelingen waar het maximale salaris groter dan of gelijk is aan het maximale salaris van afdeling 20
SELECT deptno, max(sal)
FROM employee
GROUP BY deptno
HAVING max(sal)>=(SELECT max(sal) FROM employee WHERE deptno=20);
DEPTNO MAX(SAL)
---------- ----------
20 2975
Multiple-row subquery:
Vind werknemers wier salaris gelijk is aan een van de salarissen van werknemers met de job Manager. Dit is een multiple-row subquery, omdat de subquery meer dan één rij kan teruggeven.
SELECT ename, job, sal
FROM employee
WHERE sal IN (SELECT sal FROM employee WHERE job='MANAGER');
ENAME JOB SAL
---------- --------- ----------
JONES MANAGER 2975
BLAKE MANAGER 2850
Wanneer subqueries in de FROM-clausule worden gebruikt, werken ze als een tijdelijke tabel die niet fysiek op de opslag bestaat, maar een view op de data is. Bijvoorbeeld:
SELECT e.ename, e.job, e.sal
FROM employee e, (SELECT deptno FROM department WHERE loc='DALLAS') d
WHERE e.deptno=d.deptno;
ENAME JOB SAL
---------- --------- ----------
SMITH CLERK 800
JONES MANAGER 2975
In SQL worden set-operatoren gebruikt om de resultaten van meerdere queries te combineren tot één resultaat. Het gebruikt de verzamelingenleer in de wiskunde en de bewerkingen zoals UNION, MINUS, INTERSECT. Hier zie je hoe je SET-operatoren kunt gebruiken om je queries te optimaliseren. In deze tutorial worden de volgende SET-operatoren besproken.
Informatie: Queries die SET-operatoren gebruiken, worden samengestelde statements genoemd.
UNION
Beschouw twee relaties (tabellen) R en S, dan selecteert UNION alle rijen uit R en alle rijen uit S waarbij duplicaten worden verwijderd. Het aantal geretourneerde rijen kan maximaal r+s zijn, waarbij r het aantal rijen in R is en s het aantal rijen in S.
Selecteer alle afdelingsnamen inclusief de afdelingsnamen van werknemers die vóór 23-OCT-1999 zijn aangenomen
SELECT dname
FROM department
UNION
SELECT dname
FROM department, employee
WHERE department.deptno=employee.deptno AND employee.hiredate<to_date('23-OCT-1999');
DNAME
--------------
ACCOUNTING
OPERATIONS
RESEARCH
SALES
Punten om te onthouden bij UNION:
- Het aantal kolommen en de datatypen van de geselecteerde kolommen moeten identiek zijn in alle SELECT-instructies die in de query worden gebruikt.
- De namen van de kolommen hoeven niet identiek te zijn.
- De uitvoer wordt oplopend gesorteerd op de eerste kolom van de SELECT-clausule.
- NULL-waarden worden niet genegeerd tijdens het controleren op duplicaten.
UNION ALL combineert resultaten van één of meer queries en verwijdert GEEN duplicaten, en daarom kan het sleutelwoord DISTINCT niet worden gebruikt. Beschouw een andere tabel emp die werknemers vanaf het jaar 2000 bevat. Haal alle werknemernummers, namen en jobs op uit de emp- en de employee-tabel:
SELECT empno, ename, job
FROM employee
UNION ALL
SELECT empno, ename, job
FROM emp;
EMPNO ENAME JOB
---------- ---------- ---------
7369 SMITH CLERK
7499 ALLEN SALESMAN
7521 WARD SALESMAN
7566 JONES MANAGER
7698 BLAKE MANAGER
7369 SMITH CLERK
7499 ALLEN SALESMAN
7521 WARD SALESMAN
7566 JONES MANAGER
7654 MARTIN SALESMAN
7698 BLAKE MANAGER
EMPNO ENAME JOB
---------- ---------- ---------
7782 CLARK MANAGER
7788 SCOTT ANALYST
7839 KING PRESIDENT
7844 TURNER SALESMAN
7876 ADAMS CLERK
7900 JAMES CLERK
INTERSECT
Intersectie volgt dezelfde regel als in de verzamelingenleer en geeft de gemeenschappelijke waarden uit twee verzamelingen. Beschouw twee relaties R en S, dan geeft INTERSECT de set met alle tuples die in zowel R als S voorkomen.
SELECT empno, ename, job
FROM employee
INTERSECT
SELECT empno, ename, job
FROM emp;
EMPNO ENAME JOB
---------- ---------- ---------
7369 SMITH CLERK
7499 ALLEN SALESMAN
7521 WARD SALESMAN
7566 JONES MANAGER
7698 BLAKE MANAGER
Punten om te onthouden bij INTERSECT:
- Het aantal kolommen en de datatypen van de geselecteerde kolommen moeten identiek zijn in alle SELECT-instructies die in de query worden gebruikt.
- De namen van de kolommen hoeven niet identiek te zijn.
- INTERSECT negeert NULL-waarden niet
EXCEPT en MINUS:
EXCEPT (gebruikt in SQL Server) en MINUS (Oracle-specifiek) hebben dezelfde functie. Die is: alle unieke rijen selecteren die door de eerste query zijn geselecteerd maar niet door de tweede. Om deze operator te begrijpen, bekijk de volgende tabel:

Stel, je moet een product vinden dat een hoeveelheid tussen 1 en 100 heeft maar niet tussen 50 en 75. Hier gebruik je EXCEPT als je SQL Server gebruikt en MINUS als je Oracle gebruikt.
SELECT prod_name, qty FROM products WHERE qty BETWEEN 1 AND 100 EXCEPT SELECT prod_name, qty FROM products WHERE qty BETWEEN 50 AND 75;
Voor Oracle-server:
SELECT prod_name, qty
FROM products
WHERE qty BETWEEN 1 AND 100
MINUS
SELECT prod_name, qty
FROM products
WHERE qty BETWEEN 50 AND 75;
PROD_NAME QTY
------------- ----------
COLGATE 1
SENSODYNE 100
SENSODYNE TOOTHBRUSH 30
Punten om te onthouden bij EXCEPT/MINUS:
- Het aantal kolommen en de datatypen van de geselecteerde kolommen moeten identiek zijn in alle SELECT-instructies die in de query worden gebruikt.
- De namen van de kolommen hoeven niet identiek te zijn.
- Alle kolommen in de WHERE-clausule moeten in de SELECT-clausule staan voor de MINUS-operator om te werken.
Dit is het einde van de tutorial. In deze tutorial heb je een aanzienlijke hoeveelheid SQL geleerd die je helpt SQL te beheersen in je data science-reis. SQL wordt gebruikt om rapporten uit databases te genereren. Je hebt in deze tutorial de basis van databases en SQL geleerd, veelgebruikte datatypen, functies die helpen bij het opmaken van rapporten, aggregatie van resultaten en het maken van samenvattingen, en ook manieren om data uit verschillende tabellen in de databases te verzamelen op basis van jouw eisen! Deze tutorial is specifiek ontworpen voor data science-leerlingen en helpt niet alleen met relationele databases, maar ook om soepel door NoSQL-databases te gaan en SQL-vaardigheden in Big Data-studies te gebruiken.
Wil je meer leren over SQL, volg dan de gratis cursus van DataCamp: Intro to SQL for Data Science.
Leer meer over SQL
Cursus

blog
Adel Nehme
15 min