SQL Academy · Les

EXISTS en NOT EXISTS

Controleer efficiënt op gerelateerde rijen.

Les 2 van 413 stappen

EXISTS en NOT EXISTS is een gratis SQL Academy-les op CoddyKit. Dit is les 2 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject SQL Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus SQL Academy bevat in totaal 4 lessen.

Wat is EXISTS?

De operator EXISTS controleert of een subquery minstens één rij teruggeeft. Deze evalueert naar TRUE als de subquery een resultaat oplevert en naar FALSE als de subquery leeg is.

In tegenstelling tot andere subquery-operators die waarden vergelijken, let EXISTS alleen op aanwezigheid — de operator kijkt niet naar de daadwerkelijke gegevens die de subquery teruggeeft.

Voorbeeldtabellen instellen

Voordat we EXISTS-queries schrijven, maken we twee tabellen: customers en orders. We gebruiken deze in de hele les om te onderzoeken hoe EXISTS en NOT EXISTS in de praktijk werken.

CREATE TABLE customers (
  customer_id INT PRIMARY KEY,
  name        VARCHAR(100),
  country     VARCHAR(50)
);

CREATE TABLE orders (
  order_id    INT PRIMARY KEY,
  customer_id INT,
  amount      DECIMAL(10,2),
  order_date  DATE
);

INSERT INTO customers VALUES
  (1, 'Alice',   'US'),
  (2, 'Bob',     'UK'),
  (3, 'Charlie', 'US'),
  (4, 'Diana',   'DE');

INSERT INTO orders VALUES
  (101, 1, 250.00, '2024-01-10'),
  (102, 1, 180.00, '2024-02-15'),
  (103, 2,  95.00, '2024-03-01'),
  (104, 3, 430.00, '2024-03-22');

Basissyntaxis van EXISTS

De basissyntaxis voor EXISTS plaatst deze operator binnen een WHERE-clausule. De subquery binnen EXISTS verwijst meestal naar een kolom uit de buitenste query — dit heet een gecorreleerde subquery.

De onderstaande query vindt elke klant die minstens één bestelling heeft geplaatst.

SELECT customer_id, name
FROM customers c
WHERE EXISTS (
  SELECT 1
  FROM orders o
  WHERE o.customer_id = c.customer_id
);

SELECT 1 binnen EXISTS

Je hebt misschien gemerkt dat de subquery SELECT 1 gebruikt in plaats van een echte kolom te selecteren. Dat is bewust gedaan: EXISTS controleert alleen of er rijen bestaan, niet wat ze bevatten.

Het gebruik van SELECT 1 (of zelfs SELECT *) maakt geen verschil voor het resultaat, maar SELECT 1 maakt zowel voor de database-engine als voor de lezer duidelijk dat de werkelijke waarden er niet toe doen.

-- Both of these return the same result
SELECT name FROM customers c
WHERE EXISTS (SELECT 1   FROM orders o WHERE o.customer_id = c.customer_id);

SELECT name FROM customers c
WHERE EXISTS (SELECT o.* FROM orders o WHERE o.customer_id = c.customer_id);

Hoe de database EXISTS evalueert

Voor elke rij in de buitenste query voert de database de gecorreleerde subquery uit. Zodra er één overeenkomende rij is gevonden, stopt de engine met scannen en markeert deze EXISTS als TRUE — deze kortsluitevaluatie maakt EXISTS zeer efficiënt, zelfs bij grote tabellen.

Een JOIN bouwt daarentegen eerst de volledige verzameling overeenkomende rijen op voordat er wordt gefilterd. Dat kan langzamer zijn wanneer je alleen wilt weten of er een overeenkomst bestaat.

-- EXISTS short-circuits after first match
-- Efficient even when orders table has millions of rows
SELECT name, country
FROM customers c
WHERE EXISTS (
  SELECT 1
  FROM orders o
  WHERE o.customer_id = c.customer_id
    AND o.amount > 200
);

NOT EXISTS: ontbrekende rijen vinden

NOT EXISTS is het tegenovergestelde: het retourneert TRUE wanneer de subquery geen overeenkomende rijen vindt. Dit is de standaardmanier in SQL om vragen te beantwoorden zoals "welke klanten hebben nog nooit een bestelling geplaatst?"

Als je dit probeert op te lossen met een gewone JOIN of NOT IN, kunnen er onjuiste resultaten ontstaan wanneer er NULL-waarden voorkomen — NOT EXISTS voorkomt dat probleem volledig.

-- Customers who have NOT placed any order
SELECT customer_id, name
FROM customers c
WHERE NOT EXISTS (
  SELECT 1
  FROM orders o
  WHERE o.customer_id = c.customer_id
);

NOT EXISTS versus NOT IN met NULL-waarden

Een belangrijk voordeel van NOT EXISTS ten opzichte van NOT IN is de NULL-veiligheid. Als de subquery die door NOT IN wordt gebruikt zelfs maar één NULL retourneert, wordt de volledige NOT IN-expressie NULL — waardoor de buitenste query geen rijen retourneert.

NOT EXISTS heeft geen last van dit probleem, omdat het controleert of rijen bestaan en niet of waarden gelijk zijn.

-- Dangerous: if any customer_id in orders is NULL,
-- NOT IN returns zero rows!
SELECT name FROM customers
WHERE customer_id NOT IN (SELECT customer_id FROM orders);

-- Safe: NOT EXISTS handles NULLs correctly
SELECT name FROM customers c
WHERE NOT EXISTS (
  SELECT 1 FROM orders o
  WHERE o.customer_id = c.customer_id
);

EXISTS met meerdere voorwaarden

De subquery binnen EXISTS mag elke geldige SQL bevatten, waaronder meerdere WHERE-voorwaarden. Zo kun je zeer specifieke gerelateerde rijen zoeken — bijvoorbeeld klanten die in een bepaalde maand een bestelling boven een bepaalde grens hebben geplaatst.

-- Customers who placed an order over 200 in March 2024
SELECT c.name, c.country
FROM customers c
WHERE EXISTS (
  SELECT 1
  FROM orders o
  WHERE o.customer_id = c.customer_id
    AND o.amount > 200
    AND o.order_date >= '2024-03-01'
    AND o.order_date <  '2024-04-01'
);

EXISTS in DELETE en UPDATE

EXISTS is niet beperkt tot SELECT-instructies. Je kunt het in UPDATE en DELETE gebruiken om rijen te wijzigen of te verwijderen op basis van het bestaan van gerelateerde gegevens in een andere tabel.

In het onderstaande voorbeeld worden bestellingen verwijderd die toebehoren aan klanten uit een specifiek land.

-- Delete orders placed by US customers
DELETE FROM orders o
WHERE EXISTS (
  SELECT 1
  FROM customers c
  WHERE c.customer_id = o.customer_id
    AND c.country = 'US'
);

EXISTS vergelijken met een JOIN

Met EXISTS en JOIN kun je vaak dezelfde vraag formuleren, maar ze gedragen zich verschillend. Een JOIN vermenigvuldigt rijen wanneer er meerdere overeenkomsten zijn; EXISTS retourneert elke buitenste rij hoogstens één keer.

Wanneer je alleen wilt weten of er een relatie bestaat en geen gegevens uit de gerelateerde tabel hoeft op te halen, is EXISTS overzichtelijker en doorgaans sneller.

-- JOIN may return duplicate customer rows if a customer has multiple orders
SELECT DISTINCT c.name
FROM customers c
JOIN orders o ON o.customer_id = c.customer_id;

-- EXISTS always returns each customer once
SELECT c.name
FROM customers c
WHERE EXISTS (
  SELECT 1 FROM orders o
  WHERE o.customer_id = c.customer_id
);

NOT EXISTS voor controles van gegevenskwaliteit

NOT EXISTS is een krachtig hulpmiddel voor controles van de gegevenskwaliteit. Je kunt het gebruiken om verweesde records, ontbrekende verwijzingen of rijen te vinden die gerelateerde gegevens zouden moeten hebben maar die niet hebben.

De onderstaande query detecteert orderrijen waarvan customer_id niet overeenkomt met een rij in de tabel customers — een teken dat de referentiële integriteit is beschadigd.

-- Find orders with no matching customer (orphaned records)
SELECT o.order_id, o.customer_id, o.amount
FROM orders o
WHERE NOT EXISTS (
  SELECT 1
  FROM customers c
  WHERE c.customer_id = o.customer_id
);

Korte controle

Controleer je begrip van EXISTS en NOT EXISTS.

Samenvatting van de les

In deze les heb je geleerd hoe EXISTS en NOT EXISTS je laten controleren of gerelateerde rijen aanwezig of afwezig zijn, zonder waarden rechtstreeks met elkaar te vergelijken.

Belangrijkste punten:

  • EXISTS retourneert TRUE zodra de subquery één overeenkomende rij vindt (kortsluitevaluatie).
  • NOT EXISTS retourneert TRUE wanneer de subquery geen overeenkomende rijen vindt.
  • Gebruik SELECT 1 binnen EXISTS — de geretourneerde waarden zijn niet relevant.
  • NOT EXISTS is NULL-veilig; NOT IN niet — geef de voorkeur aan NOT EXISTS wanneer er NULL-waarden kunnen voorkomen.
  • EXISTS werkt in SELECT-, UPDATE- en DELETE-instructies.
  • Wanneer je alleen wilt controleren of iets bestaat, is EXISTS vaak overzichtelijker en sneller dan een JOIN.
Gratis beginnen

Leer SQL met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
46
Lessen
183

Veelgestelde vragen

Is de les “EXISTS en NOT EXISTS” gratis?

Ja — de volledige tekst van “EXISTS en NOT EXISTS” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus SQL Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus SQL Academy bevat in totaal 4 lessen.

Wat leer ik in “EXISTS en NOT EXISTS”?

Controleer efficiënt op gerelateerde rijen. Je oefent met SQL Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met SQL Academy te beginnen?

Ervaring vooraf is niet nodig. SQL Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 2 van 4.

Hoe lang duurt de les “EXISTS en NOT EXISTS”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over SQL Academy?

Ja. Elke les over SQL Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Gecorreleerde subquery's
  2. EXISTS en NOT EXISTS
  3. IN versus ANY versus ALL
  4. EXISTS versus JOIN-prestaties
← Terug naar SQL Academy