Ana içeriğe geç
Kesit SQL
Orta · İleri Sorgu Yapıları

Özyinelemeli CTE (recursive CTE, WITH RECURSIVE)

Hiyerarşiler, ağaçlar ve sayı/tarih dizileri üretmek.

Uygulamada aç, 8 alıştırmayı çözÜcretsiz, hesap gerekmez, kurulum yok.

Bu sayfa dersin okuma sürümüdür. Metin bir kutuyu çalıştırmanı ya da adıma geçmeni söylüyorsa dersi uygulamada aç.

Kendini çağıran sorgu

Özyinelemeli CTE iki parçadan oluşur: çapa (başlangıç satırları) ve özyinelemeli kısım (bir önceki adımın sonucunu kullanır). UNION ALL ile birleştirilir ve yeni satır üretilmeyene kadar devam eder.

Sayı dizisi üretmek

WITH RECURSIVE sayilar(n) AS (
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM sayilar WHERE n < 10
)
SELECT n FROM sayilar;

Tarih iskeleti

Hiç sipariş olmayan günleri de raporda göstermek için:

WITH RECURSIVE gunler(gun) AS (
  SELECT '2024-12-01'
  UNION ALL
  SELECT date(gun, '+1 day') FROM gunler WHERE gun < '2024-12-31'
)
SELECT g.gun, COUNT(o.order_id) AS siparis
FROM gunler g
LEFT JOIN orders o ON o.order_date = g.gun
GROUP BY g.gun;

Organizasyon şeması

WITH RECURSIVE org AS (
  SELECT emp_id, first_name, manager_id, 0 AS seviye
  FROM employees WHERE manager_id IS NULL
  UNION ALL
  SELECT e.emp_id, e.first_name, e.manager_id, org.seviye + 1
  FROM employees e
  JOIN org ON e.manager_id = org.emp_id
)
SELECT * FROM org ORDER BY seviye, emp_id;
Sonsuz döngüDurma koşulunu (WHERE n < 10 gibi) unutursan sorgu bitmez. Döngü içeren verilerde (A, B'yi; B, A'yı gösteriyorsa) ziyaret edilenleri takip etmen gerekir.

Derinleş: özyinelemenin iki kullanımı

Özyinelemeli CTE ya üretmek (sayı, tarih dizisi) ya da gezmek (hiyerarşi, ağ) için kullanılır. Gezme örneği: bir müşterinin davet ettiği herkes, her kuşağıyla:

WITH RECURSIVE zincir(customer_id, kusak) AS (
  SELECT customer_id, 1 FROM lk_customers WHERE referred_by = 214
  UNION ALL
  SELECT c.customer_id, z.kusak + 1
  FROM lk_customers c JOIN zincir z ON c.referred_by = z.customer_id
)
SELECT kusak, COUNT(*) AS kisi FROM zincir GROUP BY kusak;

Döngü olabilecek verilerde (A, B'yi; B, A'yı davet etmiş gibi) bir derinlik sınırı ekle: WHERE z.kusak < 20.

Alıştırmalara geç (8)