Så fungerar rekursiva CTE:er
Basfall plus rekursivt 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 kalenderrapporter 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.
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
- Så fungerar rekursiva CTE:er
- Gå igenom ett kategoriträd
- Skapa serier och sekvenser
- Undvika oändliga loopar