Kategoriler
MySQL

SQL’in Süper Kahramanı: WITH RECURSIVE ile Hiyerarşi ve Özyineleme Macerası

Merhaba, teknoloji sevdalıları! Bugün SQL’in en havalı özelliklerinden biri olan WITH RECURSIVE ile tanışıyoruz. Bu yapı, öyle bir süper güç ki, organizasyon şemalarından tut, şehirler arası yol bulmaya kadar her türlü hiyerarşik veya döngüsel veriyi dize getiriyor. Sanki SQL’e “Hadi bakalım, biraz Matrix havası katalım!” demişiz gibi.

Hazırsan, kahvemizi kapıp bu sihirli dünyaya dalalım!

WITH RECURSIVE Ne İşe Yarıyor?

WITH RECURSIVE, SQL’de CTE (Common Table Expression) denen bir yapının özyinelemeli versiyonu. Yani, bir sorgu kendi sonuçlarını tekrar tekrar kullanıp yeni sonuçlar üretiyor. Bu, özellikle ağaç yapıları (mesela bir şirketin hiyerarşisi), grafikler (diyelim ki İstanbul’dan İzmir’e en kısa yol) veya basit bir sayı dizisi oluşturmak gibi işlerde hayat kurtarıyor.

Peki nasıl çalışıyor? İki temel parçadan oluşuyor:

  1. Temel Durum (Base Case): Hikâyenin başlangıcı. İlk veriyi buradan alıyoruz.
  2. Yinelemeli Kısım (Recursive Case): Sorgu, kendi sonuçlarını kullanarak yeni veriler üretmeye devam ediyor. Tıpkı bir filmde “devam filmi” çeker gibi!

Bu iki parça UNION ALL (ya da nadiren UNION) ile birleşiyor ve bir durdurma koşuluyla özyineleme tamamlanıyor. Hadi gel, bunu birkaç örnekle eğlenceli hale getirelim.

Örnek 1: Şirketin Patronu Kim? Hiyerarşi Sorgusu

Diyelim ki bir şirkette kimin kime bağlı olduğunu bulmamız lazım. Ahmet patron, Mehmet onun altında, Ayşe de Mehmet’in ekibinde… Bu hiyerarşiyi çözmek için WITH RECURSIVE tam bir rockstar!

Tablo Yapısı

CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    name VARCHAR(100),
    manager_id INT
);

Örnek Veri

INSERT INTO employees (employee_id, name, manager_id) VALUES
(1, 'Ahmet', NULL), -- Büyük patron!
(2, 'Mehmet', 1),
(3, 'Ayşe', 1),
(4, 'Fatma', 2),
(5, 'Ali', 2),
(6, 'Zeynep', 3);

Sorgu

WITH RECURSIVE hierarchy AS (
    -- Temel durum: En tepedeki patron
    SELECT employee_id, name, manager_id
    FROM employees
    WHERE manager_id IS NULL
    UNION ALL
    -- Yinelemeli kısım: Astları buluyoruz
    SELECT e.employee_id, e.name, e.manager_id
    FROM employees e
    INNER JOIN hierarchy h ON e.manager_id = h.employee_id
)
SELECT * FROM hierarchy;

Ne Oldu?

Bu sorgu, Ahmet’ten başlayıp tüm hiyerarşiyi tarıyor ve herkesin yerini sana döküyor. Ahmet’in altında Mehmet, Mehmet’in altında Fatma ve Ali, Ayşe’nin altında Zeynep… Sanki şirketin aile ağacını çizmişiz gibi!

Örnek 2: Sayılarla Dans Et

Bazen basit bir şey yapalım, mesela 1’den 10’a kadar sayıları listeleyelim. “Bunu döngüyle mi yazacağız?” deme, WITH RECURSIVE ile bu iş çocuk oyuncağı.

Sorgu

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

Çıktı

n
1
2
3
...
10

Bu, SQL’in “Sana sayı mı lazım? Al bakalım, şipşak!” dediği an. Küçük ama eğlenceli, değil mi?

Örnek 3: İstanbul’dan İzmir’e Yolculuk

Şimdi biraz daha havalı bir şeyler yapalım. Şehirler arası yolları düşünelim ve İstanbul’dan İzmir’e nasıl gideriz, bunu bulalım. Hem de mesafeleri hesaplayarak!

Tablo Yapısı

CREATE TABLE roads (
    city_from VARCHAR(50),
    city_to VARCHAR(50),
    distance INT
);

Örnek Veri

INSERT INTO roads (city_from, city_to, distance) VALUES
('İstanbul', 'Ankara', 450),
('Ankara', 'İzmir', 550),
('İstanbul', 'Bursa', 150),
('Bursa', 'İzmir', 300);

Sorgu

WITH RECURSIVE paths AS (
    -- Temel durum: İstanbul'dan başlayan yollar
    SELECT city_from, city_to, distance, ARRAY[city_from, city_to] AS path
    FROM roads
    WHERE city_from = 'İstanbul'
    UNION ALL
    -- Yinelemeli kısım: Diğer yolları ekle
    SELECT r.city_from, r.city_to, p.distance + r.distance, p.path || r.city_to
    FROM roads r
    INNER JOIN paths p ON r.city_from = p.city_to
    WHERE NOT r.city_to = ANY(p.path) -- Döngüye düşmeyelim!
)
SELECT * FROM paths
WHERE city_to = 'İzmir';

Çıktı

Bu sorgu, İstanbul’dan İzmir’e olan tüm yolları ve toplam mesafeleri listeliyor. Mesela:

  • İstanbul → Bursa → İzmir: 450 km
  • İstanbul → Ankara → İzmir: 1000 km

Sanki Google Maps’e kafa tutuyoruz!

Neden Bu Kadar Havalı?

WITH RECURSIVE ile neler yapabileceğine bak:

  • Hiyerarşiler: Şirket, dosya sistemi veya kategori ağaçları gibi yapıları çözmek.
  • Graf Analizi: Yol bulma, sosyal ağlar veya bağımlılık haritaları.
  • Sade Kod: Döngü yazıp kafa patlatmak yerine, SQL’in sihrine bırak kendini.

İpuçları ve Püf Noktaları

  • Döngülerden Kaçın: WHERE koşullarını iyi yaz, yoksa SQL sonsuz bir maceraya dalar!
  • UNION ALL Kullan: UNION yerine UNION ALL daha hızlı, çünkü tekrarları kontrol etmez.
  • Destek Kontrolü: PostgreSQL, MySQL 8.0+, Oracle gibi veritabanları bunu destekler. Eski bir sistem kullanıyorsan, önce kontrol et.

Son Söz

WITH RECURSIVE, SQL’in gizli bir süper kahramanı gibi. Hiyerarşileri çözmek, yolları bulmak veya sadece eğlenceli bir sayı dizisi üretmek için kullanabilirsin. Biraz pratikle, bu yapı senin veritabanı maceralarında en yakın dostun olacak. Hadi, klavyeyi kap ve bir sorgu yaz! Ne dersin, bir sonraki projende WITH RECURSIVE ile ne yapacaksın?

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir