Subquery’yi en yalın haliyle, Select içerisinde Select yazmak olarak tanımlayabiliriz.

AdventureWorks veritabanında Production.Product tablosundaki ürünlerin ilk 10’unun içerisinde rengi null olan ürünleri elde etmek isteyelim.

SELECT TOP 10 * FROM Production.Product

WHERE Color IS NULL

Ekran çıktımız,

Untitled

Ancak sorgumuzu bu şeklinde yazarsak istediğimiz sonucu elde edemeyiz. Dikkat ederseniz önce filtreleme yapılmış ve ardından ilk 10 sıradaki ürün gelmiş. Çünkü ‘WHERE’ ile filtreleme yaptığımız zaman, ilk olarak Production.Product tablosundaki tüm ürünler içerisinde rengi null olanlar filtrelenir. Yani, sadece rengi null olan ürünleri elde etmiş oluruz. Daha sonra da TOP 10 diyerek, bu filtrelenmiş ürünler arasından ilk 10 sıradakini elde ederiz. Halbuki bizim amacımız, ilk olarak renk bilgisine göre filtreleme yapmak değil, direk ilk 10 ürün arasında rengi null olanları elde etmekti.

Bu noktada Subquery’ye ihtiyaç duyarız. Sorgumuzu aşağıdaki gibi değiştirelim.

SELECT * FROM (SELECT TOP 10 * FROM Production.Product) [IlkOnUrun]

WHERE Color IS NULL

Ekran çıktımız şu şekilde olacaktır.

Untitled2

İstediğimiz sonucu elde ettik. Sorgumuzdan da anlaşıldığı gibi, ürün tablosundaki ilk 10 ürünü seçtik ve ‘WHERE’ koşulunu bu seçilen 10 ürün için yazmış olduk.

Şimdi de aynı örneği Common Table Expression kullanarak yapalım.

WITH IlkOnUrun AS

(

      SELECT TOP 10 * FROM Production.Product

)

SELECT * FROM IlkOnUrun

WHERE Color IS NULL

Ekran çıktımız yine 2. şekildeki gibi olacaktır. İki sorgu da aynı işi yapmaktadır.

 



8 yorum:

Adsız dedi ki...

cte örneği için öncelikle teşekkürler,
sormak istediğim;
cte'yi hazırladım,
Select * FROM cte şeklinde kullandım daha sonra
başka bir with içinde kullanmak istediğimde izin vermiyor acaba neden?
cursor örneğinizde gördüğüm close, Deallocate gibi komutları mı kullanmalıyım?
Teşekkürler.(recursive Cte benim ki ...)
İsmail KAYA

Onur Salkaya dedi ki...

Merhabalar,

Yazmış olduğunuz CTE ifadesini başka bir CTE içerisinde referans olarak göstermek istiyorsanız, ikinci ifade with ile başlayamaz. İki ifadeyi bir virgül ile birbirinden ayırmanız gerekmektedir. Aşağıdaki örnek sizin için daha anlamlı olacaktır.

WITH CTE AS
(
SELECT TOP 10 * From Production.Product
ORDER BY ListPrice DESC
),

MaxPriced AS
(
SELECT * FROM CTE
WHERE ListPrice>3500
)

SELECT * FROM MaxPriced

İyi çalışmalar

Adsız dedi ki...

Teşekkür ederim, fakat ben hala istediğim sorguyu oluşturamadım!

Adsız dedi ki...

CTE ile update işlemini bizlere öğretebilir misiniz acaba?
Şöyle iç içe girmiş ürün ağaçlarının fiyatlarını hesaplayabilmek aynı şekilde iç içe girmiş bölümler yöneticiler ve o bölümde çalışanların toplam fiyatı gibi...
Teşekkürler.

Adsız dedi ki...

Merhaba CTE nedir? Yani bir view ile arasındaki fark nedir? hangisi daha performanslıdır? Execution Planda mesela view daha hızlı cıkıyor. (SQL 2008) bu konuda ayrıntı verebilir misiniz? Teşekkürler.

Onur Salkaya dedi ki...

View yazmaktaki temel amaç select saklamaktır. Yani database içerisinde bir nesne gibi tutulmakta ve istediğiniz zaman bunu kullanabilme hakkına sahip olmaktasınız. Ancak CTE yazmamızdaki amaç subquery yazmaktır. View ile kıyaslamak pek doğru değil.

Serdar dedi ki...

bir şeyi anlatırken önce onun ne olduğunu ne işe yaradığını yazmak daha doğru olur direk alın baktın yaptım demek yerine

Onur Salkaya dedi ki...

Serdar Bey, zaten ne olduğunu ve ne işe yaradığını açıkladım. "Alın bakım yaptım" kısmını anlayamadım. size de eleştirilerinizde daha açık ve yapıcı olmanızı öneririm. Burada eksik gördüğünüz şeyi ve asıl olması gerekeni paylaşırsanilirsiniz mesela.

Yorum Gönder