SQL-trackLes 8 van 10

🪆 Subqueries

Queries binnen queries — gebruik resultaten van één SELECT als invoer voor een andere.

⏱ 25 min6 stappenInteractieve SQL-sandbox
Stap 1 / 6

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.

Probleem: producten duurder dan gemiddeld
Stap 1 — bereken gemiddelde prijs
SELECT AVG(prijs) FROM producten;
-- Geeft: 249.99
Stap 2 — gebruik dat getal
SELECT naam FROM producten
WHERE prijs > 249.99;
Met subquery — in één stap
SELECT naam, prijs FROM producten
WHERE prijs > (SELECT AVG(prijs) FROM producten);
In WHERE
WHERE prijs > (SELECT ...)
In SELECT
SELECT (SELECT COUNT(*) ...)
In FROM
FROM (SELECT ...) AS sub
Stap 2 / 6

IN en NOT IN met subquery

IN test of een waarde voorkomt in een lijst — die lijst kan de uitkomst zijn van een subquery.

Gebruikers die iets besteld hebben
-- 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;
NOT IN — gebruikers zonder bestelling
SELECT naam, email FROM gebruikers
WHERE id NOT IN (SELECT DISTINCT gebruiker_id FROM orders);
⚠️ NOT IN en NULL — valstrik!

Als de subquery een NULL-waarde bevat, geeft NOT IN altijd geen resultaten terug. Gebruik in dat geval NOT EXISTS als alternatief.

Stap 3 / 6

EXISTS en NOT EXISTS

EXISTS controleert of een subquery minstens één rij teruggeeft. Het is vaak sneller dan IN bij grote datasets.

EXISTS — gebruikers met bestellingen
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.

NOT EXISTS — gebruikers zonder bestellingen
SELECT naam, email FROM gebruikers AS g
WHERE NOT EXISTS (
    SELECT 1 FROM orders AS o
    WHERE o.gebruiker_id = g.id
);
IN

Maakt een volledige lijst. Bij grote datasets kan dit traag zijn. Werkt niet goed met NULL.

EXISTS

Stopt zodra er één match is. Veilig met NULL. Beter bij grote subqueries.

Stap 4 / 6

Subquery in SELECT en FROM

Subquery in SELECT — berekende kolom
-- 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;
Subquery in FROM — afgeleide tabel
-- 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;
Subquery vs JOIN — wanneer wat?
JOIN is doorgaans sneller en leesbaarder voor het combineren van tabellen
Subquery in WHERE is handig voor "bestaat er iets met eigenschap X"
Subquery in SELECT is handig voor berekende kolommen per rij
Subquery in FROM is handig voor meerstaps-berekeningen
Stap 5 / 6

Oefening — subqueries

🎯 Opdrachten
  1. Toon producten die minstens één keer besteld zijn (gebruik IN met subquery)
  2. Toon producten die nog nooit besteld zijn (NOT IN of NOT EXISTS)
  3. Toon gebruikers waarvan de leeftijd boven de gemiddelde leeftijd ligt
Resultaat verschijnt hier...

🧠 Kennischeck

🪆

Les 8 afgerond!

Je schrijft nu geneste queries en lost complexe vraagstukken op die anders meerdere stappen zouden kosten.

Les 9: Indexen & performance →