Katmanlar (örneğin, önce filtreleme yapıp, sonra gruplar bazında toplamları hesaplayıp, en son tüm veri kümesi üzerinden) ile etkili agregasyonlar inşa etmek için pencere fonksiyonları (OVER()) ve iç içe geçmiş GROUP BY kullanılır.
Örnek: Her yöneticinin yalnızca 'ödenmiş' durumundaki siparişler arasında maksimum sipariş toplamını bulalım ve ardından tümü arasında mutlak maksimum olan yöneticinin adını gösterelim.
WITH PaidOrders AS ( SELECT ManagerID, SUM(OrderAmount) AS TotalPaid FROM Orders WHERE Status = 'paid' GROUP BY ManagerID ), WithMax AS ( SELECT *, MAX(TotalPaid) OVER() AS MaxTotalPaid FROM PaidOrders ) SELECT ManagerID, TotalPaid FROM WithMax WHERE TotalPaid = MaxTotalPaid;
Bu yaklaşım (CTE + pencere fonksiyonları), çok katmanlı filtreleme ve agregasyonu gerçekleştirmeye olanak tanır.
Kandırmaca: "WHERE filtresinin gruplamadan (GROUP BY) önce çalıştırılması ile HAVING'in sonra uygulanmasının farkı nedir? Bu genellikle raporlarda ne gibi sorunlar yaratır?"
Cevap: WHERE, gruplamadan önce satırları atar, yani kesin bir giriş kümesi sağlar. HAVING, agregat gruplarını filtreler — bu nedenle mantıksal olarak uyumlu olmayan bir filtre olduğunda geçici olarak "gereksiz" satırları "bırakabilir". Filtrenin yanlış yeri, genellikle nihai agregatlarda hata veya yanlış rapor sonuçlarıyla sonuçlanır.
-- Sadece 'ödenmiş' durumundakileri WHERE ile topluyoruz SELECT ManagerID, SUM(OrderAmount) FROM Orders WHERE Status = 'paid' GROUP BY ManagerID; -- Ya da hepsini topluyoruz, ardından HAVING ile kesiyoruz SELECT ManagerID, SUM(OrderAmount) FROM Orders GROUP BY ManagerID HAVING SUM(OrderAmount) > 1000;
Hikaye
Proje: Satış raporları, denetim.
Hata: Geliştirici, agregatların yanlış bir şekilde ödenmemiş siparişleri içerdiği için HAVING Status='paid' yerine WHERE kullandı, bu nedenle personelin yıllık KPI'ları hatalı hesaplandı.
Hikaye
Proje: Banka analitiği.
Hata: Karmaşık bir agregasyona PARTITION BY olmadan pencere fonksiyonu uygulamaya çalıştılar, bu nedenle agregatlar tüm tablo üzerinden hesaplandı. Departman bütçesi hatalı bir şekilde hesaplandı — bu nedenle manuel olarak geri alma işlemi yapmak zorunda kaldılar.
Hikaye
Proje: İnternet mağazası, sipariş istatistikleri.
Hata: Optimizasyonda iç içe geçmiş pencere fonksiyonlarını göz ardı ettiler — bu nedenle sunucu verileri çoklu işleme yaptı, sorgu, sadece iki katmanlı GROUP BY ile çalışmaktan 20 kat daha yavaş hale geldi.