SQL Academy · Lektion

Så fungerar rekursiva CTE:er

Basfall plus rekursivt steg.

Lektion 1 av 413 steg

Så fungerar rekursiva CTE:er är en gratis lektion i SQL Academy på CoddyKit. Detta är lektion 1 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.

Vad är en rekursiv CTE?

En rekursiv CTE är en Common Table Expression som refererar till sig själv. Den låter er skriva frågor som upprepar ett steg tills ett villkor är uppfyllt — ungefär som en loop, men uttryckt som ren SQL.

Rekursiva CTE:er definieras med nyckelordet WITH RECURSIVE och är idealiska för att traversera hierarkiska eller grafliknande data, till exempel organisationsscheman, mappträd och stycklistor.

Strukturen i två delar

Varje rekursiv CTE består exakt av två delar, åtskilda av UNION ALL:

1. Basfall — en icke-rekursiv SELECT som returnerar startraderna.

2. Rekursivt steg — en SELECT som sammanfogar CTE:n med sig själv och producerar nästa nivå av rader.

Motorn fortsätter att köra det rekursiva steget och samla resultaten tills det inte längre produceras några nya 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;

Räkna från 1 till 5

Den enklaste rekursiva CTE:n räknar tal. Basfallet startar med värdet 1. Det rekursiva steget lägger till 1 vid varje iteration. WHERE-satsen i det rekursiva steget fungerar som avslutningsvillkor — utan den skulle frågan köras för evigt.

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

Stegvis körning

Så här bearbetar motorn räkne-CTE:n iteration för iteration:

Iteration 0 (basfall): returnerar {1}.

Iteration 1: tillämpar det rekursiva steget på {1} och returnerar {2}.

Iteration 2: tillämpar det rekursiva steget på {2} och returnerar {3}.

Iteration 3, 4: returnerar {4} och sedan {5}.

Iteration 5: WHERE n < 5 är falskt för n=5, så noll rader returneras. Frågan avslutas.

Alla ackumulerade rader — 1, 2, 3, 4, 5 — utgör slutresultatet.

Konfigurera en hierarkitabell

Rekursiva CTE:er är särskilt användbara för tabeller som refererar till sig själva. Låt oss skapa en employees-tabell där varje anställd har ett valfritt manager_id som pekar tillbaka på samma tabell.

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

Traversera hierarkin

Nu kan vi följa hela rapporteringskedjan med början hos vd:n (Alice, id=1). Basfallet väljer Alice, och det rekursiva steget hittar alla anställda vars manager_id matchar ett id som redan finns i CTE:n.

Resultatet innehåller alla anställda som kan nås från Alice, oavsett hur djupt trädet ä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;

Spåra sökvägen

En vanlig förbättring är att bygga en sökvägssträng som visar hela kedjan från roten till varje nod. Vi sammanfogar namn med ' -> ' som avgränsare medan vi går djupare i rekursionen.

Det gör det enkelt att visa navigering i brödsmulestil eller felsöka djupa 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;

Begränsa rekursionens djup

Data med stort djup eller cykler kan få en rekursiv CTE att köras mycket länge. Två säkra metoder:

1. Spåra djupet och lägg till en WHERE-sats — WHERE depth < 10 säkerställer att ni aldrig går längre än 10 nivåer.

2. Använd en kolumn för cykeldetektering — vissa databaser (PostgreSQL 14+) erbjuder syntaxen CYCLE för att automatiskt upptäcka upprepade nodbesök.

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 jämfört med UNION ALL i rekursiva CTE:er

Det rekursiva steget använder nästan alltid UNION ALL, inte UNION. Här är anledningen:

UNION tar bort dubbletter efter varje iteration genom att jämföra hela resultatuppsättningen — detta är extremt kostsamt och kan ändra semantiken för grafer där samma nod legitimt nås via flera vägar.

UNION ALL behåller alla rader utan att ta bort dubbletter, vilket både är snabbare och korrekt vid traversering av träd. Använd UNION endast när ni har ett specifikt behov av att ta bort dubbletter och förstår prestandakostnaden.

Generera en datumserie

Rekursiva CTE:er är också praktiska för att generera sekvenser av datum. Det här exemplet producerar varje dag under en viss vecka — ett mönster som ofta används för att skapa kalender­rapporter eller fylla luckor 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;

Hitta alla underställda till en chef

Ni kan initiera basfallet med vilken specifik nod som helst — inte bara roten. Här börjar vi med Bob (id=2) och hittar alla som rapporterar till honom, direkt eller indirekt.

Detta mönster är användbart för behörighetskontroller, aggregeringar av delträd eller för att begränsa instrumentpaneler till en enda avdelning.

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;

Snabbkontroll

Testa er förståelse av hur rekursiva CTE:er fungerar.

Sammanfattning av lektionen

I den här lektionen lärde ni er hur rekursiva CTE:er fungerar:

Struktur: varje rekursiv CTE har ett basfall (startrader) som sammanfogas med ett rekursivt steg (en självrefererande SELECT) genom UNION ALL.

Avslutning: motorn upprepar det rekursiva steget och samlar resultaten tills steget returnerar noll rader.

Vanliga användningsområden: följa organisationsscheman och mappträd, generera tal- eller datumsekvenser, beräkna sökvägar och hitta alla noder i ett delträd.

Säkerhetstips: inkludera alltid ett avslutningsvillkor (djupbegränsning eller cykelskydd) och föredra UNION ALL framför UNION av prestandaskäl.

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 ”Så fungerar rekursiva CTE:er” gratis?

Ja – hela texten till ”Så fungerar rekursiva CTE:er” 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 ”Så fungerar rekursiva CTE:er”?

Basfall plus rekursivt steg. 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 1 av 4.

Hur lång tid tar lektionen ”Så fungerar rekursiva CTE:er”?

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. Så fungerar rekursiva CTE:er
  2. Gå igenom ett kategoriträd
  3. Skapa serier och sekvenser
  4. Undvika oändliga loopar
← Tillbaka till SQL Academy