SQL Academy · leksjon

Anti-joins og semi-joins (NOT EXISTS)

Finn «rader i A uten treff i B» (anti-join) og «rader i A med minst ett treff i B» (semi-join) ved hjelp av EXISTS/NOT EXISTS.

Leksjon 3 av 414 trinn

Anti-joins og semi-joins (NOT EXISTS) er en gratis leksjon i SQL Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i SQL Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i SQL Academy inneholder totalt 4 leksjoner.

Semi-join: "Har minst ett treff"

Returner rader fra A som har minst én samsvarende rad i B — men bare kolonnene fra A. SQL implementerer semi-joins via EXISTS eller IN.

EXISTS-semi-join

Brukere som har lagt inn minst én ordre:

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

IN-semi-join

Samme resultat, en annen skrivemåte:

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

Hvorfor EXISTS ofte vinner

EXISTS avslutter tidlig: Den stopper ved første treff for hver ytre rad. IN kan materialisere hele det indre settet. Moderne planleggere optimaliserer ofte til samme plan, men EXISTS er det tryggeste valget for svært store indre sett.

Anti-join: "Har ingen treff"

Brukere som ALDRI har lagt inn en ordre — tre idiomatiske 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);

Hvorfor NOT IN er risikabelt

Hvis den indre underforespørselen inneholder NULL, returnerer NOT IN NULL — og WHERE forkaster rader der predikatet er NULL. Resultat: ingen rader. NOT EXISTS har ikke dette problemet.

Optimalisering i planleggeren

Moderne PostgreSQL gjenkjenner EXISTS og NOT EXISTS som semi-join- og anti-join-mønstre, og kan utføre 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 flere kolonner

Bruk sammensatte nøkler:

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 + ekstra predikat

Legg til filtre i den indre underforespørselen:

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'
);

Indekser korrelasjonskolonnen

Både EXISTS og NOT EXISTS filtrerer den indre underforespørselen på nøkkelen til den ytre raden. Uten en indeks på denne nøkkelen får De en skanning for hver ytre rad:

CREATE INDEX orders_user_id_idx ON orders(user_id);

Når LEFT JOIN ... IS NULL skal brukes

For oversikter som også trenger kolonnene fra den siden som ikke har treff, passer LEFT JOIN-stilen naturlig. For ren anti-join-semantikk er NOT EXISTS tydeligere.

Utenfor SQL: Bloom-filtre

For svært store anti-joins kan et forhåndsfilter med Bloom-filter være nyttig. PostgreSQL støtter bloom-indekser via bloom-utvidelsen.

Oppsummering

Semi-join = "har treff"; anti-join = "har ikke treff".

  • EXISTS for semi-join
  • NOT EXISTS for anti-join (NULL-sikker)
  • Indekser korrelasjonskolonnen
  • Unngå NOT IN med mindre den indre spørringen ikke kan inneholde NULL

Hurtigsjekk

De ønsker brukere som ALDRI har lagt inn en ordre. Hvilken SQL-variant er tryggest og mest idiomatisk?

Gratis å komme i gang

Lær deg SQL med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
46
Leksjoner
183

Ofte stilte spørsmål

Er leksjonen «Anti-joins og semi-joins (NOT EXISTS)» gratis?

Ja – hele teksten i «Anti-joins og semi-joins (NOT EXISTS)» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av SQL Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i SQL Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Anti-joins og semi-joins (NOT EXISTS)»?

Finn «rader i A uten treff i B» (anti-join) og «rader i A med minst ett treff i B» (semi-join) ved hjelp av EXISTS/NOT EXISTS. Du øver på SQL Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med SQL Academy?

Ingen tidligere erfaring er nødvendig. SQL Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «Anti-joins og semi-joins (NOT EXISTS)»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne SQL Academy-leksjonen?

Ja. Alle SQL Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. CROSS JOIN og kartesiske produkter
  2. Laterale sammenføyninger (LATERAL JOIN)
  3. Anti-joins og semi-joins (NOT EXISTS)
  4. Ytelsesjustering av sammenføyninger på flere tabeller
← Tilbake til SQL Academy