GROUP BY satırları gruplamak ve verileri aggrege etmek için kullanılır, ancak yanlış uygulama ciddi hatalara veya optimal olmayan çalışmalara neden olabilir.
Ana ince noktalar:
Örnek:
SELECT customer_id, COUNT(*) as orders FROM orders WHERE order_date >= '2024-01-01' GROUP BY customer_id HAVING COUNT(*) > 10;
GROUP BY'dan sonra SELECT içinde, GROUP BY'da belirtilmeyen veya aggrege fonksiyonda olmayan alanlara referans verebilir miyiz?
Cevap: Hayır, bu birçok SQL uygulamasında hata ile sonuçlanır (örneğin, MS SQL, PostgreSQL). Bazı spesifik veritabanları rastgele, yanlış bir değer gösterebilir (özellikle MySQL'de sql_mode 'ONLY_FULL_GROUP_BY' kapatıldığında), ancak bu davranış hatalıdır ve standart tarafından garanti edilmez. Doğru örnek:
SELECT department, AVG(salary) FROM employees GROUP BY department;
Hikaye
E-ticaret projesinde "ürünlere göre gelir" raporunu SELECT sku, price, SUM(qty) FROM orders GROUP BY sku sorgusuyla hazırladık. Dikkate almadık: price GROUP BY'a dahil olmadı ve aggrege fonksiyon dışında kaldı, sonuç olarak MySQL ilk rastgele fiyat değerini döndürdü, bu da kampanya döneminde raporda ciddi hatalara neden oldu. Çözüm — ya price'ı GROUP BY'a eklemek ya da aggrege fonksiyon kullanmak.
Hikaye
BI projesinde karmaşık bir rapor, çok sayıda JOIN ve GROUP BY ile 80 dakika sürdü, planlanan 3 yerine. Analizden sonra öğrendik: GROUP BY ve filtreleme için indeksler yoktu, büyük geçici tablolar oluşturuluyordu. Çözüm — indeks optimizasyonu ve sorgunun tablo ifadeleri ile yeniden yazılması.
Hikaye
Geliştirici kullanıcıların aggrege edilmemiş bir niteliğine göre değerleri filtrelemek için HAVING uyguladı. Sonuç olarak, sunucu tüm veriler üzerinden gruplama yaptı, ardından HAVING ile eleme yaptı ve performansı düşürdü. Düzelttik — bu kontrolü WHERE'e taşıyarak aggrege öncesi seçimi daralttık.