25 Haziran 2011 Cumartesi

Sql Pivotlama Kavramı

Pivotlama, kısaca satırların sütuna taşınma işlemleridir. Özellikle kurumsal firmalarda, rapor çekilirken, raporun daha okunur kılınması için veya oluşacak binlerce satırlık raporu minimize etmek için pivotlama yöntemi kullanılır. 2005 öncesi case-when yapısı kullanılarak pivotlama işlemi yapılırken, 2005 sonrası dinamik pivotlama yardımıyla artık daha kolay yapmaktayız.

Şimdi kısaca bir senaryo uydurup, beraber pivotlama yöntemiyle sorgumuzu yazalım.

Senaryomuz kısaca, AdventureWorks database'i içinde departman bazında kaç erkek, kaç bayan çalıştığını bulalım. Normal sorgulamamızı yaparsak önce departmanlara göre kaç bayan var, sonra yine departmanlara göre kaç erkek var alt alta göreceğiz, dolayısıyla satır sayısı fazla, okunulurluğu yok. Nasıl oluştuğunu görelim önce.

Sorgumuzu yazmak için 3 tabloya ihtiyacımız var. Bunlar Department, Employee ve EmployeeDepartmentHistory. Bunları birbirine joinledikten sonra cinsiyet ve departmana göre group by yapıp toplam sayı bizim istediğimiz sonuc olacak. Burada yeri gelmişken, kısaca sql'in kendi editöründen nasıl joinleme işlemlerini kolayca yapabileceğimizi göstereyim. Sorgu sayfasında herhangi bir yere sağ tıklayıp design query in editor dedikten sonra önümüze bir ekran gelecek. Add Table penceresinden yukarıda bahsettiğim üç tabloyu seçtiğimizde önümüze şu şekilde bir diyagram getirecek.


Yukarıda da görüldüğü gibi, bize sadece Gender ve Name kolonu gerektiğinden sadece onları seçiyoruz. Tabloların altında sql'in bizim için kodu kendi oluşturduğunu görüyoruz.Daha sonra oluşan kodu çalıştırdığımız zaman aşağıdaki şekilde bir sonuç kümesi geleceğiniz görürüz.


Ama biz bunu pivotlama yöntemiyle yaparsak, aşağıdaki gibi sorgu yazmamız gerekecekti. Sorgunun mantığını aşağıda anlatacağım. Önce ortaya çıkan rapor'a bakalım,



Yazacağımız kod da şu şekilde olmalıdır.

WITH CTE
as
(
SELECT Department.Name as Departman,Employee.Gender  as Cinsiyet,COUNT(HumanResources.Employee.EmployeeID) [count] FROM HumanResources.Department
INNER JOIN   HumanResources.EmployeeDepartmentHistory ON HumanResources.Department.DepartmentID = HumanResources.EmployeeDepartmentHistory.DepartmentID
INNER JOIN HumanResources.Employee ON HumanResources.EmployeeDepartmentHistory.EmployeeID = HumanResources.Employee.EmployeeID
group by Gender,Department.Name,Department.ModifiedDate                     
)
      select * from CTE PIVOT (SUM([count]) for Cinsiyet in ([F],[M])) as 

Önce CommonTableExpression ile bir tablo oluşturuyoruz. Aslında bizim pivotsuz kodumuz budur. Zaten yukarıdaki resimden de query editorun yazdığı koddan karşılaştırabilirisiniz.Bu CTE'yi yazdıktan sonra bu tablodan select * from'la tüm verileri alıyoruz fakat, 2005 yılından sonra gelen PIVOT konumu ile toplam kayıt sayısına göre Cinsiyetleri üst kolona köşeli parantez içinde yazarak kolonlara taşımış oluyoruz.

Not: En sondaki yazdığımız select sorgusunun sonuna as p diyerek bir alias veriyoruz. Bu Sql'in gözden kaçırdığı veya neden böyle bir şeyi yaptırmaya mecbur tuttuğunu anlamadığım bir zorlamasıdır. Pivotlama yaptıktan sonra, yazdığımız o sorguya alias vermek zorundayız. Aksi taktirde hata mesajı verecektir. Bu yüzden rasgele bir alias verebilirsiniz, zira daha sonra herhangi bir yerde kullanılmayacaktır.

0 yorum: