🪆 Subqueries
Queries binnen queries — gebruik resultaten van één SELECT als invoer voor een andere.
Wat is een subquery?
Een subquery (of geneste query) is een SELECT-statement dat binnen een andere query staat — tussen haakjes. Het resultaat ervan wordt gebruikt door de buitenste query.
SELECT AVG(prijs) FROM producten;
-- Geeft: 249.99
SELECT naam FROM producten
WHERE prijs > 249.99;
SELECT naam, prijs FROM producten
WHERE prijs > (SELECT AVG(prijs) FROM producten);
WHERE prijs > (SELECT ...)
SELECT (SELECT COUNT(*) ...)
FROM (SELECT ...) AS sub
IN en NOT IN met subquery
IN test of een waarde voorkomt in een lijst — die lijst kan de uitkomst zijn van een subquery.
-- Alle gebruiker-ids die in orders voorkomen
SELECT naam FROM gebruikers
WHERE id IN (SELECT DISTINCT gebruiker_id FROM orders);
-- Equivalent met JOIN:
SELECT DISTINCT g.naam FROM gebruikers g
INNER JOIN orders o ON g.id = o.gebruiker_id;
SELECT naam, email FROM gebruikers
WHERE id NOT IN (SELECT DISTINCT gebruiker_id FROM orders);
Als de subquery een NULL-waarde bevat, geeft NOT IN altijd geen resultaten terug. Gebruik in dat geval NOT EXISTS als alternatief.
EXISTS en NOT EXISTS
EXISTS controleert of een subquery minstens één rij teruggeeft. Het is vaak sneller dan IN bij grote datasets.
SELECT naam FROM gebruikers AS g
WHERE EXISTS (
SELECT 1 FROM orders AS o
WHERE o.gebruiker_id = g.id
);
De subquery verwijst naar de buitenste query via g.id — dit heet een gecorreleerde subquery.
SELECT naam, email FROM gebruikers AS g
WHERE NOT EXISTS (
SELECT 1 FROM orders AS o
WHERE o.gebruiker_id = g.id
);
Maakt een volledige lijst. Bij grote datasets kan dit traag zijn. Werkt niet goed met NULL.
Stopt zodra er één match is. Veilig met NULL. Beter bij grote subqueries.
Subquery in SELECT en FROM
-- Toon elke gebruiker + zijn aantal bestellingen
SELECT
naam,
(SELECT COUNT(*) FROM orders WHERE gebruiker_id = g.id) AS orders
FROM gebruikers AS g
ORDER BY orders DESC;
-- Gemiddelde van de categoriegemiddelden
SELECT AVG(gem_prijs) AS algeheel_gemiddelde
FROM (
SELECT categorie, AVG(prijs) AS gem_prijs
FROM producten
GROUP BY categorie
) AS categorie_stats;
Oefening — subqueries
- Toon producten die minstens één keer besteld zijn (gebruik IN met subquery)
- Toon producten die nog nooit besteld zijn (NOT IN of NOT EXISTS)
- Toon gebruikers waarvan de leeftijd boven de gemiddelde leeftijd ligt
🧠 Kennischeck
Les 8 afgerond!
Je schrijft nu geneste queries en lost complexe vraagstukken op die anders meerdere stappen zouden kosten.