Direct naar de hoofdinhoud
Module 4 · Les 4 van 416/57 in de cursus~12 min
Modulelessen (4/4)

Een query binnen een andere: subquery's

Je hebt geleerd hoe je kunt extraheren, filteren, groeperen, samenvoegen en transformeren. Daar is nog een laatste fundamenteel idee: een zoekopdracht in een andere plaatsen. Dit zijn worden subquery's genoemd en vormen de stap waarmee u vragen kunt beantwoorden zoals "wie verdient bovengemiddeld?" of "welke afdelingen hebben iemand toegewezen aan een project?".

De basissyntaxis

Een subquery is een SELECT tussen haakjes, gebruikt in plaats van een enkele waarde of een lijst met waarden in een andere query:

SQL
-- Find who earns MORE THAN THE COMPANY AVERAGE:
SELECT first_name, last_name, salary
FROM   employees
WHERE  salary > (SELECT AVG(salary) FROM employees);

De engine voert eerst de subquery uit: SELECT AVG(salary) FROM employees retourneert een enkel getal — en gebruikt dat getal vervolgens in de buitenste WHERE alsof je het met de hand hebt geschreven. Dit is precies het voordeel: dat doet u U hoeft het gemiddelde niet vooraf te weten, SQL berekent het voor u.

De drie meest voorkomende ‘types’

1. Subquery retourneert één enkele waarde

Het bovenstaande voorbeeld: de subquery produceert één rij, één kolom (genaamd scalair). Je gebruikt het met =, >, < enzovoort.

SQL
-- Employee with the highest salary:
SELECT first_name, last_name
FROM   employees
WHERE  salary = (SELECT MAX(salary) FROM employees);

2. Subquery retourneert een lijst

De subquery produceert één kolom, veel rijen. Je gebruikt het met IN (...):

SQL
-- Departments that have at least one employee:
SELECT name
FROM   departments
WHERE  id IN (SELECT DISTINCT department_id
              FROM employees
              WHERE department_id IS NOT NULL);

3. Subquery als een "tabel" (FROM)

Een subquery kan ook de plaats innemen van een tabel in FROM. Het is nuttig om bereken aggregaten vooraf en filter ze vervolgens of voeg ze samen:

SQL
-- Departments with average salary above 40000:
SELECT d.name, medie.stipendio_medio
FROM   departments AS d
JOIN  (SELECT department_id, AVG(salary) AS stipendio_medio
       FROM employees
       GROUP BY department_id) AS medie
   ON d.id = medie.department_id
WHERE  medie.stipendio_medio > 40000;

Subquery of JOIN? Wanneer gebruik je welke

Vaak kan hetzelfde resultaat worden verkregen met een JOIN of met een subquery. Vuistregel:

  • Om rijen van de ene tabel te filteren op basis van een eigenschap van een andere tabel ("werknemers wier afdelingen…"_), IN (subquery) zijn, is zeer leesbaar.
  • Gebruik JOIN om kolommen uit meerdere tabellen in het resultaat te combineren.
  • Om een aggregatie te berekenen en deze als drempel te gebruiken ("boven de gemiddelde"_), is de scalaire subquery de natuurlijke keuze.

In de praktijk zul je beide tegenkomen: de SQL-engine optimaliseert ze vaak op dezelfde manier manier. Kies het formulier dat het beste leest.

Probeer het

Oefening#sql.m4.l4.e1
Pogingen: 0Laden…

Vind de voornaam (voornaam), achternaam (achternaam) en salaris (salaris) van de werknemers die STRIKT meer verdienen dan het bedrijfsgemiddelde. Drie kolommen.

Editor laden…
Toon hint

Vervangen ? met de subquery SELECT AVG(salaris) FROM werknemers — retourneert deze een enkel getal dat als drempelwaarde kan worden gebruikt.

Oplossing beschikbaar na 3 pogingen

Oefening beoordelen

Oefening#sql.m4.l4.e2
Pogingen: 0Laden…

Vermeld de naam (departments.name) van afdelingen die ten minste één werknemer hebben met een salaris dat strikt hoger is dan 50.000. Gebruik een subquery met IN. Alfabetisch ordenen.

Editor laden…
Toon hint

De binnenste subquery retourneert de ID's van de afdelingen met werknemers met een salaris > 50000. Vervolgens WHERE id IN (...) op de buitenste query.

Oplossing beschikbaar na 3 pogingen