SQL Academy · leksjon

Slik fungerer rekursive CTE-er

Basistilfelle pluss et rekursivt trinn.

Leksjon 1 av 413 trinn

Slik fungerer rekursive CTE-er er en gratis leksjon i SQL Academy på CoddyKit. Dette er leksjon 1 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.

Hva er en rekursiv CTE?

En rekursiv CTE er en Common Table Expression som refererer til seg selv. Den lar Dem skrive spørringer som gjentar et trinn til en betingelse er oppfylt – omtrent som en løkke, men uttrykt som ren SQL.

Rekursive CTE-er defineres med nøkkelordet WITH RECURSIVE og egner seg godt til å gå gjennom hierarkiske eller graf-lignende data, for eksempel organisasjonskart, mappetrær og materiallistestrukturer.

Struktur i to deler

Alle rekursive CTE-er har nøyaktig to deler, atskilt av UNION ALL:

1. Ankerdel – en ikke-rekursiv SELECT som returnerer startradene.

2. Rekursivt trinn – en SELECT som kobler CTE-en tilbake til seg selv og produserer neste nivå med rader.

Motoren fortsetter å kjøre det rekursive trinnet og samle resultater til det ikke produserer noen nye rader.

WITH RECURSIVE cte_name AS (
  -- Base case
  SELECT ...
  UNION ALL
  -- Recursive step (references cte_name)
  SELECT ... FROM source JOIN cte_name ON ...
)
SELECT * FROM cte_name;

Telle fra 1 til 5

Den enkleste rekursive CTE-en teller tall. Ankerdelen starter med verdien 1. Det rekursive trinnet legger til 1 i hver iterasjon. WHERE-klausulen i det rekursive trinnet fungerer som avslutningsbetingelse – uten den ville spørringen kjørt for alltid.

WITH RECURSIVE counter(n) AS (
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM counter WHERE n < 5
)
SELECT n FROM counter;

Utførelse trinn for trinn

Slik behandler motoren teller-CTE-en, iterasjon for iterasjon:

Iterasjon 0 (ankerdel): returnerer {1}.

Iterasjon 1: bruker det rekursive trinnet på {1} og returnerer {2}.

Iterasjon 2: bruker det rekursive trinnet på {2} og returnerer {3}.

Iterasjon 3 og 4: returnerer først {4} og deretter {5}.

Iterasjon 5: WHERE n < 5 er usann for n=5, så ingen rader returneres. Spørringen avsluttes.

Alle radene som er samlet inn – 1, 2, 3, 4 og 5 – utgjør det endelige resultatet.

Sette opp en hierarkitabell

Rekursive CTE-er er spesielt nyttige med tabeller som refererer til seg selv. La oss opprette en employees-tabell der hver ansatt har en valgfri manager_id som peker tilbake til den samme tabellen.

CREATE TABLE employees (
  id       INTEGER PRIMARY KEY,
  name     VARCHAR(50),
  manager_id INTEGER REFERENCES employees(id)
);

INSERT INTO employees VALUES
  (1, 'Alice',   NULL),
  (2, 'Bob',     1),
  (3, 'Carol',   1),
  (4, 'Dave',    2),
  (5, 'Eve',     2),
  (6, 'Frank',   3);

Gå gjennom hierarkiet

Nå kan vi gå gjennom hele rapporteringskjeden med utgangspunkt i administrerende direktør (Alice, id=1). Ankerdelen velger Alice, og det rekursive trinnet finner alle ansatte der manager_id samsvarer med en id som allerede finnes i CTE-en.

Resultatet omfatter alle ansatte som kan nås fra Alice, uansett hvor dypt treet går.

WITH RECURSIVE org_tree AS (
  SELECT id, name, manager_id, 0 AS depth
  FROM employees
  WHERE manager_id IS NULL
  UNION ALL
  SELECT e.id, e.name, e.manager_id, ot.depth + 1
  FROM employees e
  JOIN org_tree ot ON e.manager_id = ot.id
)
SELECT depth, name FROM org_tree ORDER BY depth, name;

Spore stien

En vanlig forbedring er å bygge en stistreng som viser hele kjeden fra roten til hver node. Vi setter sammen navnene med ' -> ' mellom etter hvert som vi går dypere i rekursjonen.

Dette gjør det enkelt å vise brødsmulenavigasjon eller feilsøke dype hierarkier.

WITH RECURSIVE org_tree AS (
  SELECT id, name, name AS path
  FROM employees
  WHERE manager_id IS NULL
  UNION ALL
  SELECT e.id, e.name, ot.path || ' -> ' || e.name
  FROM employees e
  JOIN org_tree ot ON e.manager_id = ot.id
)
SELECT name, path FROM org_tree ORDER BY path;

Begrense rekursjonsdybden

Dype eller sirkulære data kan føre til at en rekursiv CTE kjører svært lenge. To trygge fremgangsmåter:

1. Spor dybden og legg til en WHERE-klausul – WHERE depth < 10 sikrer at De aldri går forbi 10 nivåer.

2. Bruk en kolonne for syklusdeteksjon – noen databaser (PostgreSQL 14+) tilbyr syntaksen CYCLE for automatisk å oppdage gjentatte besøk på noder.

WITH RECURSIVE org_tree AS (
  SELECT id, name, 0 AS depth
  FROM employees
  WHERE manager_id IS NULL
  UNION ALL
  SELECT e.id, e.name, ot.depth + 1
  FROM employees e
  JOIN org_tree ot ON e.manager_id = ot.id
  WHERE ot.depth < 10
)
SELECT depth, name FROM org_tree;

UNION eller UNION ALL i rekursive CTE-er

Det rekursive trinnet bruker nesten alltid UNION ALL, ikke UNION. Her er grunnen:

UNION fjerner duplikater etter hver iterasjon ved å sammenligne hele resultatsettet – dette er svært kostbart og kan endre betydningen for grafer der samme node med rette nås via flere stier.

UNION ALL beholder alle rader uten å fjerne duplikater, noe som både er raskere og korrekt ved gjennomgang av trær. Bruk UNION bare når De har et konkret behov for å fjerne duplikater og forstår ytelseskostnaden.

Generere en datoserie

Rekursive CTE-er er også nyttige for å generere sekvenser av datoer. Dette eksempelet produserer hver dag i en bestemt uke – et mønster som ofte brukes til å lage kalender­rapporter eller fylle hull i tidsseriedata.

WITH RECURSIVE date_series AS (
  SELECT DATE '2024-01-01' AS day
  UNION ALL
  SELECT day + INTERVAL '1 day'
  FROM date_series
  WHERE day < DATE '2024-01-07'
)
SELECT day FROM date_series;

Finne alle underordnede til én leder

De kan starte ankerdelen med en hvilken som helst bestemt node – ikke bare roten. Her starter vi med Bob (id=2) og finner alle som rapporterer direkte eller indirekte til ham.

Dette mønsteret er nyttig for tilgangskontroller, aggregasjoner av undertrær eller for å begrense dashbord til én enkelt avdeling.

WITH RECURSIVE subordinates AS (
  SELECT id, name
  FROM employees
  WHERE id = 2
  UNION ALL
  SELECT e.id, e.name
  FROM employees e
  JOIN subordinates s ON e.manager_id = s.id
)
SELECT name FROM subordinates;

Hurtigsjekk

Test forståelsen Deres av hvordan rekursive CTE-er fungerer.

Oppsummering av leksjonen

I denne leksjonen lærte De hvordan rekursive CTE-er fungerer:

Struktur: Alle rekursive CTE-er har en ankerdel (startrader) som kobles til et rekursivt trinn (en selvrefererende SELECT) med UNION ALL.

Avslutning: Motoren gjentar det rekursive trinnet og samler resultater til trinnet returnerer null rader.

Vanlige bruksområder: gå gjennom organisasjonskart og mappetrær, generere tall- eller datosekvenser, beregne stier og finne alle noder i et under tre.

Sikkerhetstips: Ta alltid med en avslutningsbetingelse (dybdebegrensning eller sykluskontroll), og foretrekk UNION ALL fremfor UNION av hensyn til ytelsen.

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 «Slik fungerer rekursive CTE-er» gratis?

Ja – hele teksten i «Slik fungerer rekursive CTE-er» 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 «Slik fungerer rekursive CTE-er»?

Basistilfelle pluss et rekursivt trinn. 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 1 av 4.

Hvor lang tid tar leksjonen «Slik fungerer rekursive CTE-er»?

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. Slik fungerer rekursive CTE-er
  2. Gå gjennom et kategoritre
  3. Generere serier og sekvenser
  4. Unngå uendelige løkker
← Tilbake til SQL Academy