SQL CTE Nedir? WITH Kullanımı ve Recursive CTE Örnekleri


CTE, karmaşık bir sorgu içinde geçici ve isimlendirilmiş bir sonuç kümesi tanımlamayı sağlar. Açılımı Common Table Expression’dır ve WITH ifadesiyle yazılır.

CTE fiziksel bir tablo oluşturmaz. Tanımlandığı sorgu kapsamında kullanılabilir.

Temel CTE örneği

WITH CustomerSales AS (
    SELECT
        CustomerID,
        SUM(Amount) AS TotalAmount
    FROM Orders
    GROUP BY CustomerID
)
SELECT
    CustomerID,
    TotalAmount
FROM CustomerSales
WHERE TotalAmount > 10000;

Önce müşteri toplamları hesaplanır, ardından ana sorguda 10.000 üzerindeki müşteriler filtrelenir.

CTE neden kullanılır?

  • İç içe alt sorguları okunabilir hâle getirir.
  • Dönüşüm adımlarına anlamlı isim verir.
  • Aynı sorguda çok aşamalı hesaplama kurmayı kolaylaştırır.
  • Hiyerarşik veriler için recursive sorgu yazmayı sağlar.
  • Karmaşık SQL kodunun test edilmesini kolaylaştırır.

CTE ve alt sorgu farkı

Aynı sonuç çoğu zaman alt sorguyla da üretilebilir:

SELECT *
FROM (
    SELECT CustomerID, SUM(Amount) AS TotalAmount
    FROM Orders
    GROUP BY CustomerID
) s
WHERE TotalAmount > 10000;

CTE’nin temel avantajı okunabilirlik ve adımları ayırmaktır. CTE kullanmak sorgunun otomatik olarak daha hızlı çalışacağı anlamına gelmez; veritabanı yürütme planı ayrıca incelenmelidir.

Birden fazla CTE kullanımı

WITH MonthlySales AS (
    SELECT
        CustomerID,
        YEAR(OrderDate) AS SalesYear,
        MONTH(OrderDate) AS SalesMonth,
        SUM(Amount) AS MonthlyAmount
    FROM Orders
    GROUP BY
        CustomerID,
        YEAR(OrderDate),
        MONTH(OrderDate)
),
CustomerAverage AS (
    SELECT
        CustomerID,
        AVG(MonthlyAmount) AS AvgMonthlyAmount
    FROM MonthlySales
    GROUP BY CustomerID
)
SELECT *
FROM CustomerAverage
ORDER BY AvgMonthlyAmount DESC;

CTE’ler virgülle ayrılır; ikinci CTE önceki CTE’nin sonucunu kullanabilir.

Recursive CTE nedir?

Recursive CTE kendi sonucuna tekrar başvurarak hiyerarşik yapıları dolaşır. Organizasyon şeması, ürün ağacı ve kategori hiyerarşisi örnektir.

WITH EmployeeTree AS (
    SELECT
        EmployeeID,
        ManagerID,
        EmployeeName,
        0 AS LevelNo
    FROM Employees
    WHERE ManagerID IS NULL

    UNION ALL

    SELECT
        e.EmployeeID,
        e.ManagerID,
        e.EmployeeName,
        t.LevelNo + 1
    FROM Employees e
    INNER JOIN EmployeeTree t
        ON e.ManagerID = t.EmployeeID
)
SELECT *
FROM EmployeeTree;

İlk bölüm başlangıç kayıtlarını, ikinci bölüm bir sonraki seviyeyi bulur.

CTE kullanırken sık yapılan hatalar

CTE’yi kalıcı tablo sanmak

CTE yalnızca kendisini takip eden ifade kapsamında geçerlidir.

Sıralamanın korunduğunu varsaymak

Sonuç sırası gerekiyorsa ana SELECT içinde ORDER BY kullanın.

Recursive CTE’de bitiş koşulu kurmamak

Hatalı ilişki veya döngü gereksiz tekrar oluşturabilir. Hiyerarşi anahtarlarını doğrulayın.

Büyük sonucu tekrar tekrar kullanmak

CTE her senaryoda ara sonucu fiziksel olarak saklamaz. Sonuç birçok kez kullanılacaksa geçici tablo veya farklı tasarım daha uygun olabilir.

CTE ne zaman kullanılmalı?

  • Adım adım okunması gereken rapor sorgularında
  • Önce toplulaştırıp sonra filtreleme yapılacağında
  • Window function sonucuna ek filtre uygulanacağında
  • Hiyerarşik veri çözüleceğinde

JOIN temelini güçlendirmek için SQL JOIN türleri rehberini okuyun. Sorguları interaktif SQL eğitiminde deneyebilirsiniz.

Sık sorulan sorular

CTE view ile aynı şey mi?

Hayır. View veritabanında tanımlanan kalıcı bir nesnedir; CTE tek sorgu kapsamında yaşar.

CTE performansı artırır mı?

Tek başına performans garantisi vermez. Okunabilirliği artırır; gerçek performans yürütme planı, indeksler ve veri hacmine bağlıdır.

CTE içinde JOIN kullanılabilir mi?

Evet. SELECT içinde kullanılabilen JOIN, GROUP BY ve window function gibi yapılar CTE içinde de kullanılabilir.

Ali Rıza Ekici

İş Zekâsı, Qlik Sense, ETL, SAP, SQL ve veri analitiği üzerine uygulamalı içerikler hazırlıyor.

Yazar ve deneyim hakkında →