SQL Academy · Lektion

Anti-joins och semi-joins (NOT EXISTS)

Hitta ”rader i A utan matchning i B” (anti-join) och ”rader i A med minst en matchning i B” (semi-join) med EXISTS/NOT EXISTS.

Lektion 3 av 414 steg

Anti-joins och semi-joins (NOT EXISTS) är en gratis lektion i SQL Academy på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för SQL Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i SQL Academy innehåller totalt 4 lektioner.

Semi-join: ”har minst en träff”

Returnera rader från A som har minst en matchande rad i B – men endast kolumnerna från A. SQL implementerar semi-joins via EXISTS eller IN.

EXISTS-semi-join

Användare som har lagt minst en beställning:

SELECT u.* FROM users u
WHERE EXISTS (
  SELECT 1 FROM orders o WHERE o.user_id = u.id
);

IN-semi-join

Samma resultat, en annan stil:

SELECT * FROM users
WHERE id IN (SELECT user_id FROM orders);

Varför EXISTS ofta vinner

EXISTS avslutar tidigt: sökningen stoppas vid den första träffen för varje yttre rad. IN kan materialisera hela den inre mängden. Moderna planerare optimerar ofta till samma plan, men EXISTS är det säkrare valet för mycket stora inre mängder.

Anti-join: ”har ingen träff”

Användare som ALDRIG har lagt en beställning – tre idiomatiska former:

-- NOT EXISTS (preferred):
SELECT u.* FROM users u
WHERE NOT EXISTS (
  SELECT 1 FROM orders o WHERE o.user_id = u.id
);

-- LEFT JOIN ... IS NULL:
SELECT u.* FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE o.id IS NULL;

-- NOT IN (risky with NULLs):
SELECT * FROM users WHERE id NOT IN (SELECT user_id FROM orders);

Varför NOT IN är riskabelt

Om den inre underfrågan innehåller NULL returnerar NOT IN NULL – och WHERE tar bort rader där predikatet är NULL. Resultat: noll rader. NOT EXISTS har inte detta problem.

Optimering av planeraren

Moderna versioner av PostgreSQL känner igen EXISTS och NOT EXISTS som semi-/anti-join-mönster och kan köra dem med hash-joins:

EXPLAIN ANALYZE
SELECT u.* FROM users u
WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);
-- → Hash Anti Join

Anti-joins med flera kolumner

Använd sammansatta nycklar:

SELECT * FROM order_items oi
WHERE NOT EXISTS (
  SELECT 1 FROM shipments s
  WHERE s.order_id = oi.order_id
    AND s.line_no  = oi.line_no
);

Semi-join med EXISTS + ytterligare predikat

Lägg till filter i den inre underfrågan:

SELECT u.* FROM users u
WHERE EXISTS (
  SELECT 1 FROM orders o
  WHERE o.user_id = u.id
    AND o.status = 'paid'
    AND o.created_at >= NOW() - INTERVAL '30 days'
);

Indexera korrelationskolumnen

Både EXISTS och NOT EXISTS filtrerar den inre underfrågan med den yttre radens nyckel. Utan ett index på den nyckeln får ni en genomsökning per yttre rad:

CREATE INDEX orders_user_id_idx ON orders(user_id);

När LEFT JOIN ... IS NULL ska användas

För kontrollpaneler som även behöver kolumnerna från den omatchade sidan passar LEFT JOIN-stilen naturligt. För ren anti-join-semantik är NOT EXISTS tydligare.

Bortom SQL: Bloom-filter

För mycket stora anti-joins kan ett förfilter med Bloom-filter hjälpa. PostgreSQL stöder bloom-index via tillägget bloom.

Sammanfattning

Semi-join = ”har träff”; anti-join = ”saknar träff”.

  • EXISTS för semi-join
  • NOT EXISTS för anti-join (NULL-säkert)
  • Indexera korrelationskolumnen
  • Undvik NOT IN om den inre mängden kan innehålla NULL

Snabb kontroll

Ni vill hitta användare som ALDRIG har lagt en beställning. Vilken SQL-fråga är säkrast och mest idiomatisk?

Gratis att börja

Lär dig SQL med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
46
Lektioner
183

Vanliga frågor

Är lektionen ”Anti-joins och semi-joins (NOT EXISTS)” gratis?

Ja – hela texten till ”Anti-joins och semi-joins (NOT EXISTS)” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i SQL Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i SQL Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Anti-joins och semi-joins (NOT EXISTS)”?

Hitta ”rader i A utan matchning i B” (anti-join) och ”rader i A med minst en matchning i B” (semi-join) med EXISTS/NOT EXISTS. Ni övar på SQL Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig SQL Academy?

Du behöver inga förkunskaper. Utbildningen i SQL Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Anti-joins och semi-joins (NOT EXISTS)”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här SQL Academy-lektionen?

Ja. Varje SQL Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Cross joins och kartesiska produkter
  2. Laterala kopplingar (LATERAL JOIN)
  3. Anti-joins och semi-joins (NOT EXISTS)
  4. Prestandajustering av kopplingar mellan flera tabeller
← Tillbaka till SQL Academy