- PIVOT ne yapar, hangi sorunu çözer?
- Her veritabanında çalışan yöntem: koşullu toplulaştırma
- SQL Server'da PIVOT operatörü
- Sütunlar önceden bilinmiyorsa: dinamik pivot
- Pivotu tersine çevirmek: UNPIVOT
- Sık yapılan hatalar ve kontrol listesi
- Mindset programlarında bu beceri nerede çalışılır?
- Sık sorulan sorular
SQL'de Satırları Sütuna Çevirme: PIVOT ve Çapraz Tablo Sorguları
SQL'de satırları sütuna çevirmeyi PIVOT operatörü ve CASE ile koşullu toplulaştırma yöntemleriyle, dinamik pivot ve UNPIVOT dahil örneklerle öğrenin.
PIVOT ne yapar, hangi sorunu çözer?
Veritabanları veriyi uzun biçimde, yani her olay ayrı satırda saklar: bir satış satırı, ürün, ay ve tutar bilgisini taşır. Rapor ise sıklıkla geniş biçim ister: satırlarda ürünler, sütunlarda aylar, hücrelerde toplam tutar. Satırları sütuna çevirme işlemine pivot, ortaya çıkan tabloya çapraz tablo (cross tab) denir.
Pivot şu işleri birlikte yapar: bir sütundaki benzersiz değerleri sütun başlığına dönüştürür ve bu başlıkların altındaki değerleri bir toplulaştırma fonksiyonuyla (toplam, sayı, ortalama) özetler. Bu yüzden pivot, yalnızca yeniden düzenleme değil, aynı zamanda gruplamadır.
Örneğin sipariş tablosunda her satır bir ürün satışı olsun. Ay bazında ürün kırılımı isteyen bir yönetici, uzun tabloyu doğrudan okuyamaz; aylar sütuna çevrildiğinde karşılaştırma tek bakışta yapılır. Ayrıca pivot sonucu sıklıkla bir grafik aracına ya da Excel'e doğrudan verilir.
Her veritabanında çalışan yöntem: koşullu toplulaştırma
PIVOT operatörü her veritabanında yoktur. Taşınabilir yöntem, CASE ifadesiyle koşullu toplulaştırmadır. Her sütun için bir koşul yazılır ve yalnızca o koşula uyan satırlar toplama girer:
SELECT product, SUM(CASE WHEN ay = 'Ocak' THEN tutar END) AS ocak, SUM(CASE WHEN ay = 'Şubat' THEN tutar END) AS subat, SUM(CASE WHEN ay = 'Mart' THEN tutar END) AS mart FROM satislar GROUP BY product;
Burada ELSE yazılmadığı için koşula uymayan satırlar NULL üretir; SUM bu satırları yok sayar. Bu yazım hem okunaklıdır hem MySQL, PostgreSQL, SQL Server ve Oracle'da aynı çalışır. Sayım için aynı kalıp COUNT(CASE WHEN koşul THEN satir_kimligi END) şeklinde kurulur; COUNT yalnızca NULL olmayan değerleri saydığı için doğru sonuç verir.
PostgreSQL'de aynı iş için FILTER cümlesi de kullanılabilir:
SELECT product, SUM(tutar) FILTER (WHERE ay = 'Ocak') AS ocak, SUM(tutar) FILTER (WHERE ay = 'Şubat') AS subat FROM satislar GROUP BY product;
Koşullu toplulaştırmanın bir bedeli vardır: sütun listesi sorguya elle yazılır. Yeni bir ay ya da ürün ortaya çıkarsa sorguya yeni satır eklemek gerekir.
SQL Server'da PIVOT operatörü
SQL Server (T-SQL) PIVOT operatörünü doğrudan destekler. Microsoft belgesine göre PIVOT, bir sütundaki benzersiz değerleri çıktıda sütun başlığına çevirir ve gerekli yerlerde toplulaştırma yapar. Yapı şudur: önce pivot için gerekli sütunları üreten bir kaynak sorgu, sonra toplulaştırma fonksiyonu, hangi sütunun değerlerinin başlık olacağı ve hangi değerlerin listeleneceği.
SELECT product, [Ocak], [Şubat], [Mart] FROM ( SELECT product, ay, tutar FROM satislar ) AS kaynak PIVOT ( SUM(tutar) FOR ay IN ([Ocak], [Şubat], [Mart]) ) AS pvt;
Kaynak sorguya yalnızca gerekli sütunları koymak önemlidir. PIVOT, kaynakta bulunan diğer sütunları gruplama anahtarı sayar; gereksiz bir sütun (örneğin sipariş numarası) satırların birleşmesini engeller ve her satırı ayrı bir grup yapar. Bu, yeni başlayanların PIVOT sonucunda "neden hâlâ çok satır var?" diye sormasının en yaygın nedenidir.
Belge ayrıca şu uyarıyı yapar: toplulaştırma fonksiyonlarında değer sütunundaki NULL değerler hesaba katılmaz. Yani COUNT ile saydığınız sütun NULL içeriyorsa sonuç beklediğinizden düşük çıkabilir. Aynı belge, tek bir sorguda PIVOT ve UNPIVOT'u çok tekrarlamanın performansı olumsuz etkileyebileceğini de not eder. Oracle da benzer bir PIVOT cümlesi sunar; MySQL'de böyle bir operatör bulunmadığı için koşullu toplulaştırma kullanılır.
Sütunlar önceden bilinmiyorsa: dinamik pivot
Sütun adları değişkense (örneğin her ay yeni bir ay sütunu eklenecekse), sütun listesini sorgu kendi içinde üretemez; SQL sorguyu çalışmadan önce sütun yapısını bilmek zorundadır. Çözüm dinamik SQL'dir: sütun listesi önce ayrı bir sorguyla toplanır, sonra komut metni olarak birleştirilip çalıştırılır.
Bu yöntem bazı riskler taşır. İlki güvenliktir: sütun adları dışarıdan gelen veriden oluşuyorsa SQL enjeksiyonuna açık hale gelir, bu yüzden adlar güvenli biçimde tırnaklanmalıdır. İkincisi sürdürülebilirliktir: metin birleştirmeyle oluşan sorgu okunması ve test edilmesi zor bir yapıya dönüşür.
PostgreSQL'de bu ihtiyaç için tablefunc eklentisindeki crosstab fonksiyonu kullanılabilir; yine de çıktı sütunlarının tip ve sayısını çağrıda tanımlamak gerekir. Birçok ekip, dinamik pivotu veritabanında değil, rapor aracında ya da uygulama katmanında yapmayı tercih eder. Excel, Power BI ve benzeri araçlar zaten kendi pivot mekanizmasına sahiptir; veritabanı yalnızca uzun biçimde temiz veriyi sunar.
Pivotu tersine çevirmek: UNPIVOT
Elinizdeki tablo zaten geniş biçimde ise (aylar ayrı sütunlarda) ve analiz için uzun biçime ihtiyaç varsa, ters işlem gerekir. SQL Server UNPIVOT operatörüyle bunu sunar; sütun adlarını bir sütundaki değere, hücre değerlerini başka bir sütuna dönüştürür. Belgeye göre UNPIVOT, PIVOT'un birebir tersi değildir: PIVOT toplulaştırma yaparak satırları birleştirdiği için orijinal satırlar geri gelmez; ayrıca UNPIVOT girdisindeki NULL değerler çıktıda kaybolur.
Taşınabilir yöntem UNION ALL'dur: her sütun için ayrı bir SELECT yazılır ve sonuçlar alt alta birleştirilir.
SELECT product, 'Ocak' AS ay, ocak AS tutar FROM rapor UNION ALL SELECT product, 'Şubat', subat FROM rapor UNION ALL SELECT product, 'Mart', mart FROM rapor;
Uzun biçim, filtreleme ve gruplama için daha esnektir; geniş biçim ise sunum içindir. Veri modeli kurarken depolama için uzun, rapor katmanında geniş biçim kullanmak iyi bir kuraldır.
Sık yapılan hatalar ve kontrol listesi
Pivot sorgularında tekrarlayan hatalar şunlardır:
- Kaynak sorguya gereksiz sütun eklemek ve satırların beklenmedik biçimde birleşmemesi
- NULL değerleri hesaba katmamak; COUNT ve SUM sonuçları yanılttığında farkı bulmak zor olur
- Hiç eşleşmeyen satır için sıfır beklemek; koşullu toplulaştırmada eşleşme yoksa sonuç NULL döner, sıfır göstermek için COALESCE kullanılır
- Sütun değerlerini yanlış yazmak; 'Subat' ile 'Şubat' farklı değerdir ve sessizce boş sütun üretir
- Sütun sıralamasına güvenmek; ay gibi sıralı kategorilerde sıra sorguda açıkça verilmelidir
Çalıştırmadan önce kısa bir kontrol: pivot öncesi toplam ile pivot sonrası satır toplamlarının toplamı eşit olmalıdır. Eşit değilse listelenmeyen bir değer, NULL ya da yanlış yazılmış bir kategori vardır. Toplam kontrolü, pivot sorgusunda en ucuz doğrulama yoludur.
Mindset programlarında bu beceri nerede çalışılır?
Pivot ve çapraz tablo, rapor hazırlayan veri analistleri, finans ve operasyon raporlaması yapan ekipler için günlük bir ihtiyaçtır. Mindset'in SQL ile Veri Sorgulama (İleri) programı CTE, alt sorgu, pencere fonksiyonları ve ileri vaka çalışmalarını ele alarak bu tür dönüşüm sorgularının üzerine kurulduğu temeli sağlar. SQL ile İleri Veri Dönüşümü ve Modelleme programı ise olgu tabloları ve toplulaştırma, boyut modelleme desenleri gibi konularla dönüşüm tarafını genişletir.
Kurumsal ekiplerde finans ve operasyon raporlamasını elle Excel'de yapan çalışanların bu sorguları öğrenmesi, tekrarlanan raporları otomatikleştirir. Program sayfaları kapsamı ayrıntılı gösterir; PIVOT operatörünün işlendiği yer için güncel müfredat sayfasına bakmak gerekir.
İlgili Mindset programı
SQL ile Veri Sorgulama (İleri)
Sık sorulan sorular
SQL'de PIVOT her veritabanında çalışır mı?
Hayır. SQL Server ve Oracle PIVOT operatörünü sunar. MySQL ve PostgreSQL'de bu operatör yoktur; onun yerine CASE ile koşullu toplulaştırma kullanılır, PostgreSQL'de ayrıca FILTER cümlesi ve tablefunc eklentisindeki crosstab bulunur. Koşullu toplulaştırma yöntemi tüm bu sistemlerde aynı çalıştığı için taşınabilirdir.
Pivot sonucunda satır sayısı neden azalmıyor?
Kaynak sorguda pivot ve değer sütunu dışında başka sütunlar varsa, PIVOT onları gruplama anahtarı sayar. Sipariş numarası gibi benzersiz bir sütun her satırı ayrı grup yapar. Çözüm, kaynak sorguya yalnızca gerekli sütunları koymaktır.
Pivotta boş hücreler neden NULL geliyor?
Bir kombinasyon için hiç satır yoksa toplulaştırma NULL üretir. Rapor için boş yerine sıfır isteniyorsa sonucu COALESCE ile sarmalayın. Ancak NULL ile gerçek sıfır farklı anlamlar taşır: ilkinde veri yoktur, ikincisinde veri vardır ve toplamı sıfırdır. Bu ayrım raporda gerekiyorsa korunmalıdır.
Sütun sayısı değişiyorsa pivot nasıl yapılır?
SQL, sütun yapısını sorgu çalışmadan bilmek zorundadır. Dinamik SQL ile sütun listesi önce toplanıp komut metnine eklenir ya da PostgreSQL'de crosstab kullanılır. Güvenlik için sütun adları tırnaklanmalıdır. Pratikte birçok ekip, dinamik pivotu rapor aracında yapar.
UNPIVOT, PIVOT'u geri alır mı?
Tam olarak değil. PIVOT toplulaştırma yaparak satırları birleştirdiği için orijinal satırlar geri gelmez. SQL Server belgesine göre UNPIVOT girdisindeki NULL değerler de çıktıda kaybolur. Taşınabilir alternatif, her sütun için bir SELECT yazıp UNION ALL ile birleştirmektir.
İlgili rehberler
İlgili eğitimler
Kategori: Veri Analitiği ve İş Zekası