Yayınlandı - Per, 14 Ara 2023

Her Yönüyle CTE(Common Table Expression) Kavramı

Her Yönüyle CTE(Common Table Expression) Kavramı

Bu yazımızda Sql Server 2005 ile birlikte kullanılmaya başlayan CTE kavramını etraflıca ele alacağız.

Öncelikle CTE'nin tanımını yapalım. CTE(Common Table Expression), geçici tablo yada türemiş tablo gibi davranan, DB'de object (tablo, sp, view vs..) gibi depolonmayan ve tek bir SELECT, INSERT, UPDATE, DELETE veya CREATE VIEW ifadelerinin derhal peşine(!) kullanılan geçici sonuç kümelerine denir. Türetilmiş tabloların aksine, CTE'ler sorgu içinde kendine referans edilebilir ve yine kendisini birden fazla kez çağırabilir. (Varsayılan olarak üst limit 100 defadır ancak bu sayıyı isteğe göre arttırabilirsiniz.) En basit haliyle CTE nin yazım şekli şöyledir;
 
WITH CTE_ismi(sütun isimleri)
 
AS
(cte_sorgusu)
 
SELECT|INSERT|UPDATE|DELETE...FROM...CTE_ismi
 
Nasılki bir stored procedure, view ya da tablo tanımlarken "create view" şeklinde cümleye başlıyoruz, CTE tanımlarken'de cümlemiz WITH anahtar sözcüğü ile başlar.
Örnek uygulamalara başlamadan önce aşağıdaki 2 tabloyu veritabanınıza kayıt etmenizi rica ediyorum.
   
CREATE TABLE tblEmployee
(
Id int not null primary key,
Name varchar(50),
Gender varchar(10),
DepartmentID int
)
 
GO
 
INSERT INTO tblEmployee(Id, Name, Gender, DepartmentID) VALUES
 
(1, 'John', 'Male', 3),
(2, 'Mike', 'Male', 2),
(3, 'Pam', 'Female',1),
(4, 'Todd', 'Male', 4),
(5, 'Sara', 'Female', 1),
(6, 'Ben', 'Male',3)
 
CREATE TABLE tblDepartment
(
DeptId int not null primary key,
DeptName varchar(50)
)
 
GO
 
INSERT INTO tblDepartment(DeptId, DeptName) VALUES
(1, 'IT'),
(2, 'Payroll'),
(3, 'HR'),
(4, 'Admin')
 
 
 
 
Resim-1'de belirtilen sorguya dikkat edecek olursak CTE tanımlarken kontrol etmemiz gereken en önemli husus, AS'den sonra gelen parantez içi ana sorgu'dan dönen kolon sayısı ile, CTE içinde tanımladığınız kolon sayısının aynı olmasıdır ve tabi bunların karşılıklı sıralaması da benzer olmalıdır çünkü birbirleriyle eşlenik bir hal alıyorlar. Siz içerdeki sorguyu çalıştırarak geçici bir sorgu kümesi oluşturuyorsunuz ve bunu CTE ile tanımlanan bölüme atıyorsunuz. Daha sonra ise tanımladığınız CTE'yi çağırarak bunu işleme sokuyorsunuz. Dikkat edilmesi gereken diğer bir husus ise CTE yi çağırdıktan sonra şayet kendisini bir tablo gibi işleme sokacaksanız(join gibi), bu hususta CTE tanımlarken yazdığınız parantez içi değerlerinin aşağıdaki çağırma işleminde olduğu gibi kolon isimlerinin aynı olmasıdır. Zira CTE bu aşamadan sonra bir tablo gibi davranacaktır ve sizin yukarda tanımlamış olduğunuz kolon isimlerine bağlı oluyor olmanız beklenmektedir.
Önemli not: CTE tanımladıktan sonra parantez içine sütun adı yazmak mecburu değildir. Bunu yazarak sadece algıda seçicilik vurgulanıyor.
 
 
Şimdi dilerseniz, makalenin en başında italik harflerle yapmış olduğum CTE nin tanımından yola çıkarak bir örnek yapalım.  
 
En baştaki CTE tanım cümlemizden yola çıkacak olursak; CTE ler yaratıldıktan sonra derhal çağrılmalıdır ve araya başka herhangi bir sorgu girmemelidir. Aksi takdirde ana sorgunuz çalışmayacaktır. Resim-2'deki örneğe bakacak olursak araya yazmış olduğum 'Merhaba' Select'i bu durumla benzeşen bir örnektir ve yazım şekli olarak bilinmesinde fayda olacağını düşünüyorum.
 
 
Multiple CTE Kavramı
 
Bir CTE içersinde birden fazla CTE sorgusu aralara virgül koyularak yazılabilir. Daha sonra bu sorgular SET operatörleri ile (UNION ALL, UNION, EXCEPT yada INTERSECT gibi) birleştirilir.Örneğin;
 
WITH EmployeesCountBy_Payrol_IT(DepartmentName, Total)
AS
(
SELECT d.DeptName, COUNT(Id) as TotalEmployees
FROM tblEmployee e JOIN tblDepartment d on e.DepartmentID= d.DeptId
WHERE d.DeptName IN ('Payroll', 'IT')
GROUP BY d.DeptName
),
EmployeesCountBy_HR_Admin(DepartmentName, Total)
AS
(
SELECT d.DeptName, COUNT(e.Id) as TotalEmployees
FROM tblEmployee e JOIN tblDepartment d on e.DepartmentID= d.DeptId
WHERE d.DeptName IN ('HR','Admin')
GROUP BY d.DeptName
)
 
SELECT* FROM EmployeesCountBy_HR_Admin
UNION
SELECT* FROM EmployeesCountBy_Payrol_IT
 
 
Bu şekilde aralara virgül koyarak birden fazla CTE sorgusu yazmanız mümkün.
 
 
 Bir CTE güncellenebilir mi ?
 
Bu sorunun cevabı hem evet hem de hayır'dır. Şayet CTE sorgunuz içersinde yazan tablolardan sadece biri bu update'den etkileniyor ise pekâla olabilir ancak birden fazla tablo bu durumdan etkileniyor ise güncelleme olmaz. Örneğin;
WITH Employees_Name_Gender
AS
(
SELECT Id, Name, Gender
FROM tblEmployee
)
 
SELECT* FROM Employees_Name_Gender
 
 
Yukarıdaki sorgunun sonuç kümesi için Resim-3'ü inceleyiniz.
 
Şimdi bu sonuç kümesini CTE sorgusu üzerinden update edelim:
 
WITH Employees_Name_Gender
AS
(
SELECT Id, Name, Gender FROM tblEmployee
)
UPDATE Employees_Name_Gender
SET Gender = 'Female' WHERE Id = 1
 
Sonuç aşağıdaki gibi olacaktır.
 
Bakınız Resim-4.
 
Gördüğünüz gibi sorgu sonucumuz başarılı şekilde geldi.
 
Peki. 2 tabloyu birleştirip update işlemi yapalım birde:
 
Bakınız Resim-5.
 
Bu sorgudan da anlaşılacağı üzere 2 adet ana tabloya sahip bir CTE'de update işleminden etkilenen tablo sayısı 1 adet olduğu için işlemimiz başarılı bir şekilde gerçekleşti.
 
Peki sorgumuzu Resim-6'daki gibi güncellersek sonuç ne olur ?
 
Gördüğünüz gibi sorgumuz çalışmadı. Çünkü update sorgumdan farklı 2 tablo etkileniyor..
Şimdide farklı bir update örneğine bakacağız. Resim-7'yi inceleyecek olursak;
 
Bu örnekte where koşulunda belirttiğimiz Id = 1 eklentisi PK gibi değil tıpkı bir etiket(label) gibi çalışır ve departman tablosunu gözönüne alarak, bölümü HR olanların tümünü IT ye çevirir.
 
CTE için Update işlemlerini toparlayacak olursak;
 
1) Eğer update işleminin bağlı olduğu tablo adedi bir ise dolayısı ile etkilenecek tablo adedi de haliyle 1 ise, UPDATE işlemi problemsiz çalışır.
2) Şayet CTE sorgusunda birden fazla tablo var ise ve UPDATE işlemi bu birden fazla tabloyu etkiliyor ise UPDATE işlemine izin verilmez ve sorgu sonucu hata ekranı gelir.
3) Eğer bir CTE birden fazla tablo sorgusu içeriyorsa ve UPDATE den etkilenecek tablo adedi 1 ise, UPDATE sorunsuz çalışır ancak istenilen sonucu alamazsınız. (Son örneğimizde olduğu gibi..)
 
Recursive CTE Yapısı
 
Recursive CTE, sorgu içersinde kendisini çağıran CTE tipine denir. Bu tip örnekler daha çok çalışan-yönetici arasındaki hiyerarşiyi kurmak için kullanılırlar.
 
 
Elimizde örnek veri olması açısından aşağıdaki sorguyu çalıştırmanızı rica ediyorum.
 
CREATE TABLE Employee
(  
Id int not null primary key,  
Name varchar(50),
ManagerID int  
)  
 
GO
 
INSERT INTO Employee(Id, Name, ManagerID) VALUES
(1, 'Tom',  2),
(2, 'Josh',  NULL),  
(3, 'Mike',2),  
(4, 'John',  3),  
(5, 'Pam',  1),  
(6, 'Mary', 3),
(7, 'James',  1),
(8, 'Sam', 5),
(9, 'Simon',1)
 
 
Resim-8'de görmüş olduğunuz şekil bir self-join örneğidir. Biz şimdi bu örnek üzerinden CTE kullanarak bir çalışan-yönetici hiyerarşisi kuracağız. En tepe yöneticiden başlayarak aşşağıya doğru sıralı olarak numaralandırma yapacağız.  
 
 
Resim-9'daki şekli inceleyecek olursak; içerdeki sorguda CTE nin çağrıldığını görüyoruz (CTE nin Recursive özelliğinden ötürü) ve hiyerarşik olarak sayısal değer ataması yapabilmek için ana tabloyla çağırdığımız CTE yi birleştiriyoruz. NULL olan satır, hiyerarşinin tepe noktasında olacağı içinde başlangıç olarak 1 değerini atıyoruz. Bir diğer önemli husus; [Level] anahtar sözcüğü dışarıdan bir sütun olarak eklendiği için yazım kuralı olarak '[]' aralığında ifade edilmiştir.

CTE ile ilgili olarak benim anlatacaklarım bu kadar. Umuyorumki faydalı bir yazı olmuştur. Bir sonraki yazımda görüşmek üzere.

Oluşturan

Furkan Aslan

Sevimli bir projeci...

Merhaba, ben Furkan. Yazılım sektöründe 12 senelik geçmişe sahip bir proje yöneticisiyim.

Genel olarak, proje yönetimi ile ilgileniyorum.

Profili Görüntüle

Yorumlar (0)

Arama Yap
Popüler Kategoriler
En Son Eklenen Blog
Robots.txt Dosyası Hakkında
Robots.txt Dosyası Hakkında
Web sitenizin arama motoru robotları ile iletişime geçip, istediğiniz sayfa veya dizinlerin indekslenmesini robots.txt dosyası ile sağlayabilirsiniz.SEO açısından oldukça mühim ve dikkat bir çekici konu olan robots.txt dosyalarının oluşturulma hikayesi ilk olarak 1994 yılında gündeme gelmiştir. Bu dosyanın mucidi, dünyanın ilk arama motoru olan aliweb'in de kurucusu olan Martijin Koster tarafından bulunmuştur. Ne amaçla kullanılır?Sahip olduğunuz web sitenizde değerli içerik linklerinin yanı sıra iletişim, hakkımda, gizlilik sözleşmesi, sıkça sorulan sorular gibi sitenin footer kısmında yer alan alanların google arama sonuçlarında çıkmasını engellemek maksadıyla kullanılan bir yöntemdir. Nasıl Oluşturulur ?Robots.txt dosyasını oluşturmak için herhangi bir programlama bilgisine ihtiyaç yoktur. Bilgisayarınızda notepad dosyası açıp bunu robots.txt ismiyle kaydediyor olmanız bu işin ilk aşamasıdır. Sonrasında ise bu dosyayı kök dizine atıyor olmanız gerekir. Yani URL nizin aktif hali şu şekilde olacaktır: sitenizinadi.com/robots.txt Robots.txt içeriğindeki komutlar nelerdir ?Bu dosya üç komuttan oluşur: 1) User-agent : İlgili komutun hangi robota uygulandığını ifade eder."*" derseniz tüm robotları kapsasın anlamı taşır. 2) Disallow : Ziyaret edilmesini istemediğiniz kısımları buraya yazıyorsunuz. "Disallow:/linkadi" şeklinde yazılır. "Disallow:" şeklinde bir yazım ise herhangi bir kısıt olmadığını, tüm web sitesinin robot tarafından taranabileceğini ifade eder. 3) Allow : Botlar tarafından taranmasını istediğiniz alanları buraya yazabilirsiniz. Bu arada belirtmekte fayda var. Birden fazla alanı alt alta "Allow :" diyip tanımlayabilirsiniz. Bunların dışında yorum satırı eklemek isterseniz, "#" işaretini kullanmanız gerekir. Bu işaretden sonra yazılan sözcükler google botları tarafından görülmez.

Per, 14 Ara 2023

MsSQL de FileStream ve FileTable Kavramları
MsSQL de FileStream ve FileTable Kavramları
Günümüzde artık veritabanı sunucuları, yapısal verilerin dışında yapısal olmayan verileride tutmaya yöneliyor. Ses dosyaları, resimler, mailler, video dosyaları, ofis belgeleri vb..Her geçen dakika hatta saniye, yönetebileceğimizden fazla veri üretiyoruz. Günümüzde potansiyel olarak kullandığımız verilerin yaklaşık %80'inin yapısal olmayan türde veriler olduğu ifade ediliyor. Bilgisayar donanımlarının (görece) bu yüksek kapasitedeki verileri depolayarak analiz yapabilecek seviyeye gelmesi oldukça karmaşık bir durum. Karmaşıklıktan kastım bu verilerin etkili bir şekilde saklanması ve bunların sağlıklı analizi diyebilirim. Aynı zamanda bu iş için harcanacak efor gücünün de ayrı meşakkat olduğunu belirtmek isterim. Bu karmaşıklıktan ötürüdürki, şimdilik bu tarz verilerin analizi kurumlar için "Dark Data" diye tabir edilen karanlık tarafta, aydınlanmayı bekliyor.. Esas konumuzun özelinde bir giriş yapacak olur isek; Sql server'ın yapısal olmayan veriler için sunduğu güzel bir özellik vardır: FILESTREAM..Sql 2008 ile birlikte gelen bu yapıda verileriniz NTFS disk sisteminde duruyor. Size düşen ise bu verilerinizi T-SQL kodlarıyla sorgulamak. Yani filestream, sql-server ile diskiniz arasında köprü görevi görüyor desek heralde yanılmış olmayız. Bu işlemin bana göre en büyük yararı audit dediğimiz yetkilendirme safhasından nasibini alması. İstediğiniz dosyaya read-only ataması yapıp yine bu dosyalara kimlerin erişeceği ile alakalı yetki ataması yapabilirsiniz. FILETABLE'da yine filestream ile aynı mantıkta çalışan hatta bu teknolojinin üzerine bina edilmiş daha ileri bir versiyondur diyebiliriz. Bu özellik ise sql 2012 ile birlikte gelmiştir. Sizin bu teknolojiyi kullanabilmeniz için iki seviyede işlem yapıyor olmanız gerekmektedir. 1-Instance seviyesinde, 2-Veritabanı seviyesinde.

Per, 14 Ara 2023

20 Soruda SQL
20 Soruda SQL
Bu kez 20 adet soruyla sql bilgimizi sınıyoruz.<a href = "Images/sqlsorular.docx" target="_blank">  Sizler için farklı konu başlıklarında 20 adet sql sorusu hazırladım. Cevapları dökümanın sonunda görebilirsiniz. Dökümanı indirmek için buraya tıklayınız. İyi çalışmalar dilerim. </a>

Per, 14 Ara 2023

Tüm Bloglar