Common Table Expression (CTE) Nedir, Ne Değildir ?

SQL Server 2005 ile birlikte sunulan CTE (Common Table Expression – Ortak Tablo İfadeleri), bir sorgunun yürütülmesi anında elde edilmiş geçici sonuçlar bir veya daha fazla kere kullanılmasını sağlayan ifadelerdir. CTE bir table veya view olmayıp sadece bir sorgu ifadesidir. Yani geçici ve kalıcı tablolar gibi herhangi bir veri içermezler. Bir CTE’nin basit yazım biçimi aşağıdaki gibidir;

WITH expression_name [ ( column_name [,...n] ) ]
AS
( CTE_query_definition )

CTE’ler WITH sözcüğüyle tanımlanır. CTE’lerin en önemli özelliği kendi kendini çağırabiliyor olması ve aynı sorgu içerisinden birden fazla çalıştırılabiliyor olmasıdır. Bu özelliğiyle CTE’ler daha çok recursive(Öz-yinelemeli) işlemler için geliştirilmiştir diyebiliriz. Örnek olarak hiyerarşik listeler için tercih edilir. Bu tür işlemler için geçici tablolar kullanılabiliyor olsa da CTE’ler daha iyi bir performans sağlar. En azından tablo okuma ve işlemler gibi herhangi bir log izi oluşturmaz.
CTE’ler table ve view yapılarından farklı olarak primary key, unique, not null, default. gibi constraint’ler desteklemez. Aslında olmayan birşeyden daha doğrusu sadece çağrıldıkları anda oluşan bir yapıdan bahsediyoruz.
CTE’ler yalnızca SELECT değil INSERT, UPDATE ve DELETE yapılarında da kullanılabilir.

Aşağıdaki içeriğe sahip Kategori ve Urun isminde 2 tablo olduğunu düşünelim.

Kategori tablosunu sorgulamayı en basit CTE yapısıyla şu şekilde yazabiliriz;

WITH cteKat(KategoriId, KategoriAdi)
AS
(
	SELECT KategoriId, KategoriAdi FROM Kategori
)   

SELECT * FROM cteKat

Şimdi aralarında hiyerarşik ilişki bulunan kategorileri seviyelerine göre listeleyelim. Yani hangi kategori hangi kategoriye bağlı görünüyor.

WITH cteKat(KategoriId, KategoriAdi, UstKategoriAdi, Seviye)
AS
(
	--Başlangıç Sorgusu
	SELECT KategoriId, KategoriAdi, CAST('' as VARCHAR(10)) UstKategoriAdi, 1 Seviye
		FROM Kategori WHERE UstKategoriId IS NULL
	UNION ALL
	--Biriktirme Sorgusu
	SELECT K1.KategoriId, K1.KategoriAdi, K2.KategoriAdi UstKategoriAdi, Seviye+1 Seviye
		FROM Kategori K1 INNER JOIN cteKat K2 ON K1.UstKategoriId=K2.KategoriId
)   

SELECT * FROM cteKat


Görüldüğü gibi cursor, while gibi döngüsel işlemler yapmadan kolayca kendine atıfta bulunan bir sorgu yazmış olduk. CTE ile yapılmış başka bir örnek için SQL Server Önceki Satırların Toplamı makalesine göz atılabilir.

Common Table Expression (CTE) Nedir, Ne Değildir ?” hakkında 4 yorum

  1. haluk

    Selam
    WITH cteKat(KategoriId, KategoriAdi, UstKategoriAdi, Seviye)
    AS
    (
    –Başlangıç Sorgusu
    SELECT KategoriId, KategoriAdi, CAST(” as VARCHAR(10)) UstKategoriAdi, 1 Seviye
    FROM Kategori WHERE UstKategoriId IS NULL
    UNION ALL
    –Biriktirme Sorgusu
    SELECT K1.KategoriId, K1.KategoriAdi, K2.KategoriAdi UstKategoriAdi, Seviye+1 Seviye
    FROM Kategori K1 INNER JOIN cteKat K2 ON K1.UstKategoriId=K2.KategoriId
    )

    SELECT * FROM cteKat

    çalışmıyor.
    Kodları neden kontrolsüz ekliyorsunuz siteye

    Cevapla
  2. selim hapeloglu

    Bende hata aldım
    Msg 240, Level 16, State 1, Line 2
    Types don’t match between the anchor and the recursive part in column “UstKategoriAdi” of recursive query “cteKat”.

    Cevapla
  3. Ahmet Kaymaz Yazar

    Selim Bey,

    bu hatayı tablodaki KategoriAdi alanının türünün farklı olmasından alıyorsunuzdur. Kategori tablosunda KategoriAdi alanının tipi ne ise CTE’de de aynısını yazmanız gerekiyor. Benim örneğimde tablodaki KategoriAdi alanını türü VARCHAR(10) dur. Tablonun CREATE scripti şu şekildedir;

    CREATE TABLE Kategori(
    KategoriId INT,
    KategoriAdi VARCHAR(10),
    UstKategoriId INT
    )

    INSERT Kategori VALUES(1,’K1′,NULL)
    INSERT Kategori VALUES(2,’K2′,NULL)
    INSERT Kategori VALUES(3,’K11′,1)
    INSERT Kategori VALUES(4,’K12′,1)
    INSERT Kategori VALUES(5,’K21′,2)
    INSERT Kategori VALUES(6,’K13′,1)
    INSERT Kategori VALUES(7,’K121′,4)

    Cevapla

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir