GROUP BY satırları ezer, pencere fonksiyonu ezmez
GROUP BY her grup için tek satır döndürür. Ama bazen hem ayrıntıyı hem özeti aynı satırda isteriz: “Her çalışanın maaşı ve departmanının ortalaması”. Pencere fonksiyonu tam olarak budur.
SELECT first_name, dept_id, salary,
AVG(salary) OVER (PARTITION BY dept_id) AS dept_ort,
salary - AVG(salary) OVER (PARTITION BY dept_id) AS fark
FROM employees
WHERE dept_id IS NOT NULL;
OVER (): Pencere tüm sonuç kümesidir.OVER (PARTITION BY x): Her x grubu ayrı bir penceredir.OVER (ORDER BY y): Pencere sıralıdır; toplamalar kümülatif olur (sonraki derste).
Paya oranlamak
Her kategorinin toplam içindeki payı:
SELECT category,
COUNT(*) AS urun,
ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER (), 1) AS yuzde
FROM products
GROUP BY category
ORDER BY urun DESC;
Burada SUM(COUNT(*)) OVER () “tüm grupların sayılarının toplamı” demektir; pencere fonksiyonları GROUP BY'dan sonra çalıştığı için bu mümkündür.
Nerede kullanılamaz?Pencere fonksiyonları SELECT ve ORDER BY'da kullanılabilir; WHERE, GROUP BY ve HAVING'de kullanılamaz. Pencere sonucuna göre filtrelemek için sorguyu CTE/alt sorguya sarman gerekir.
Derinleş: GROUP BY ile pencereyi birlikte kullanmak
Pencere fonksiyonu GROUP BY'dan sonra çalışır; bu yüzden bir toplamın toplamını alabilir. Her mutfak türünün teslimler içindeki payı:
SELECT r.cuisine,
COUNT(*) AS siparis,
ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER (), 1) AS pay
FROM lk_orders o
JOIN lk_restaurants r ON r.restaurant_id = o.restaurant_id
WHERE o.status = 'teslim'
GROUP BY r.cuisine;SUM(COUNT(*)) OVER (): önce her grup sayılır, sonra tüm grupların sayıları toplanır.