SQL'de CTE nedir? WITH ile sorguya isim vermek

2 Ağustos 2026·6 dk okuma·Her sorgu tarayıcında çalışır

CTE, isim verilmiş bir alt sorgudur. Konsept bu kadar. WITH muhendisler AS (…) tanımı yapar; ana sorgu FROM muhendisler diyerek ondan, sanki bir tabloymuş gibi seçer. Tek bir sorgu boyunca yaşar, sonra yok olur. CTE hakkında söylenen her şey — okunabilirlik, tekrar kullanım, özyineleme — bir adıma isim verebilmenin sonucudur.

Her şeyi anlatan tek sorgu

Bir CTE — SQL Quest'in employees tablosunda çalışır
WITH muhendisler AS (
  SELECT name, salary, hire_date
  FROM employees
  WHERE department = 'Engineering'
)
SELECT name, salary
FROM muhendisler
WHERE salary > 90000
ORDER BY salary DESC;

Yukarıdan aşağı okunur: önce "mühendisler" ne demek onu tanımla, sonra asıl soruyu sor (90 binden fazla kazananlar). İç içe alt sorgu içten dışa okunur; CTE ise tarif gibi — 1. adım, 2. adım, cevap.

Hız hakkında dürüst not: CTE sorguyu hızlandırmaz (genelde yavaşlatmaz da). Modern motorlar — PostgreSQL 12+, MySQL 8+, SQL Server, SQLite — CTE'yi alt sorgu yazmışsın gibi içeri açar. CTE bir okunabilirlik aracıdır; "CTE yavaştır" efsanesi, yıllar önce ölen PostgreSQL ≤11 davranışından kalmadır.

Herkesin düştüğü tuzak: sütun kapsamı

CTE, yalnızca kendi SELECT'inde yazdığın sütunları dışarı verir. Alttaki tablonun sütunlarını değil — kendininkileri:

✗ Hata — hire_date CTE'nin içinde yok
WITH muhendisler AS (
  SELECT name, salary FROM employees WHERE department = 'Engineering'
)
SELECT name, salary, hire_date   -- ✗ no such column: hire_date
FROM muhendisler;

hire_date elbette employees tablosunda var — ama muhendisler, employees değil; senin tanımladığın iki sütunluk sonuç. Hata mesajı tabloda gördüğün bir sütunu "yok" diye bildiriyorsa, CTE'nin gerçekte ne seçtiğine bak. Çözüm mekanik: sütunu CTE'nin SELECT'ine ekle.

Virgülle çoklu CTE: isimli adımlardan boru hattı

İki CTE — ikincisi birincisini kullanıyor
WITH muhendisler AS (
  SELECT name, salary FROM employees WHERE department = 'Engineering'
),
kidemliler AS (
  SELECT name, salary FROM muhendisler WHERE salary > 90000
)
SELECT COUNT(*) AS kidemli_sayisi, ROUND(AVG(salary)) AS ort_maas
FROM kidemliler;

Tek WITH, tanımlar arasında virgül; her CTE üstündekileri kullanabilir. Karmaşık raporun okunur kalma sırrı budur: filtrele → zenginleştir → topla, her adımın adı var, her adım son SELECT'i değiştirerek tek başına test edilebilir.

▶ Pratik: Sorguya İsim Ver (WITH)

Ne zaman CTE gereksiz?

Sık sorulanlar

CTE neyin kısaltması?

Common Table Expression — "ortak tablo ifadesi". İsim, kavramdan karışık: "isimli alt sorgu" üç kelimeden daha iyi anlatır.

CTE ile VIEW farkı ne?

Kapsam. VIEW veritabanı şemasında yaşayan kayıtlı bir sorgudur, her sorgu kullanabilir. CTE tek bir ifade için vardır. Aynı fikir — sorguya isim vermek — iki farklı ömürde.

WITH RECURSIVE ne zaman lazım?

Derinliği bilinmeyen hiyerarşilerde: organizasyon şeması, kategori ağacı, yorum zincirleri. İngilizce derin anlatım: Recursive CTE explained.

CTE'yi okudun. Şimdi refleks yap.

Soru iki dakika sürer, tarayıcında çalışır; Koç yanlış CTE'nin nerede yanlış olduğunu anlatır — kapsam tuzağı dahil, istersen Türkçe.

CTE Pratiği — Ücretsiz →