DBAtlas · Veritabanı operasyon atlası

Özyinelemeli CTE (WITH RECURSIVE)

Oracle

-- CONNECT BY ile hiyerarşi:
SELECT id, ad, yonetici_id, LEVEL
FROM calisan
START WITH yonetici_id IS NULL
CONNECT BY PRIOR id = yonetici_id;

-- Alternatif (11gR2+): standart özyinelemeli WITH (RECURSIVE anahtar kelimesi yazılmaz)
WITH agac (id, ad, yonetici_id) AS (
  SELECT id, ad, yonetici_id FROM calisan WHERE yonetici_id IS NULL
  UNION ALL
  SELECT c.id, c.ad, c.yonetici_id
  FROM calisan c JOIN agac a ON c.yonetici_id = a.id
)
SELECT * FROM agac;

Hiyerarşik (ağaç) veriyi gezmek için kullanılır: organizasyon şeması, ürün ağacı gibi. Oracle'ın klasik yolu CONNECT BY / PRIOR ve LEVEL sözde sütunudur; START WITH kök satırı belirler. 11gR2 sonrası standart özyinelemeli CTE de desteklenir.

PostgreSQL

WITH RECURSIVE agac (id, ad, yonetici_id, seviye) AS (
  SELECT id, ad, yonetici_id, 1
  FROM calisan WHERE yonetici_id IS NULL
  UNION ALL
  SELECT c.id, c.ad, c.yonetici_id, a.seviye + 1
  FROM calisan c JOIN agac a ON c.yonetici_id = a.id
)
SELECT * FROM agac ORDER BY seviye;

WITH RECURSIVE bir başlangıç (anchor) sorgusu ile bir özyineli parçayı UNION ALL ile birleştirir; özyineli parça sonuç boşalana kadar tekrar çalışır. Hiyerarşi ve grafik yürüyüşü için idealdir. Sonsuz döngüye karşı UNION (ALL yerine) veya döngü koruması kullanın.

MySQL

WITH RECURSIVE agac (id, ad, yonetici_id, seviye) AS (
  SELECT id, ad, yonetici_id, 1
  FROM calisan WHERE yonetici_id IS NULL
  UNION ALL
  SELECT c.id, c.ad, c.yonetici_id, a.seviye + 1
  FROM calisan c JOIN agac a ON c.yonetici_id = a.id
)
SELECT * FROM agac ORDER BY seviye;

MySQL 8.0 (ve MariaDB 10.2+) WITH RECURSIVE söz dizimini standarda uygun destekler. Özyineleme derinliği cte_max_recursion_depth sistem değişkeniyle sınırlanır (varsayılan 1000). Eski sürümlerde stored procedure ile döngü yazmak gerekirdi.

SQL Server

WITH agac (id, ad, yonetici_id, seviye) AS (
  SELECT id, ad, yonetici_id, 1
  FROM calisan WHERE yonetici_id IS NULL
  UNION ALL
  SELECT c.id, c.ad, c.yonetici_id, a.seviye + 1
  FROM calisan c JOIN agac a ON c.yonetici_id = a.id
)
SELECT * FROM agac ORDER BY seviye
OPTION (MAXRECURSION 100);

SQL Server'da özyinelemeli CTE için RECURSIVE anahtar kelimesi yazılmaz; UNION ALL içeren CTE otomatik özyineli sayılır. Varsayılan özyineleme sınırı 100'dür; OPTION (MAXRECURSION n) ile değiştirilir (0 = sınırsız, dikkatli kullanın).

MongoDB

// En yakın karşılık: $graphLookup aşaması
db.calisan.aggregate([
  { $match: { yonetici_id: null } },
  { $graphLookup: {
      from: "calisan",
      startWith: "$id",
      connectFromField: "id",
      connectToField: "yonetici_id",
      as: "astlar"
  } }
])

MongoDB'de özyinelemeli CTE yoktur; hiyerarşik gezinme için $graphLookup aggregation aşaması kullanılır. connectFromField/connectToField bağlantı alanlarını, maxDepth ise derinlik sınırını belirler. Ağaç ve grafik ilişkilerini tek sorguda çözer.

Redis

# Uygulanamaz: Redis'te özyinelemeli sorgu yoktur.

Redis sorgu dili sunmaz. Hiyerarşi/graf gezintisi uygulama kodunda ya da sunucu tarafında Lua betiğiyle yapılır; çekirdek Redis'te ağaç yürüyüşü istemci tarafında yazılır. (Eskiden kullanılan RedisGraph modülünün desteği 2023'te sona erdi.)

Elasticsearch

# Uygulanamaz: özyinelemeli sorgu desteklenmez.
# Yaklaşım: parent-child (join alanı) veya nested ile modelleme,
# derin hiyerarşiler uygulama tarafında dolaşılır.

Elasticsearch özyinelemeli sorgu (WITH RECURSIVE / CONNECT BY karşılığı) sunmaz. Hiyerarşik ilişkiler 'join' (parent/child) alan tipiyle veya ağaç yolunu (materialized path) bir alanda saklayarak modellenir; çok seviyeli gezinme genelde uygulamada yapılır.

DBAtlas'ta aç →