Modül dersleri (4/4)
Grupları filtreleme: HAVING
Grup başına bir sonuç elde ettiğinizde (önceki ders), genellikle
yalnızca bir koşulu karşılayan grupları tutun: daha fazlasına sahip bölümler
2 kişiden fazla, ortalama bütçesi 100 binin üzerinde olan projeler,
en az 10 sipariş. Bunu yapmak için WHERE yeterli değil.
NEREDE neden yeterli değil
WHERE, toplamadan _önceki tablo satırlarını filtreler. Yani göremiyor
COUNT(*) veya AVG(...) sonucu: WHERE çalıştırıldığında, bunlar
değerler henüz hesaplanmamıştır.
-- ERROR: COUNT(*) doesn't exist yet when WHERE is evaluated
SELECT department_id, COUNT(*) AS count
FROM employees
WHERE COUNT(*) > 2 -- ❌ doesn't work
GROUP BY department_id;Toplama sonrasında filtrelemek için özel bir cümle vardır: HAVING.
Sözdizimi
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM table
GROUP BY grouping_column
HAVING condition_on_aggregate;-- Departments with more than 2 employees:
SELECT department_id, COUNT(*) AS count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 2;HAVING GROUP BY için ne ise WHERE FROM için odur: aynı fikir
("filtre"), ancak toplu olarak gruplandırmadan sonra uygulanır.
Cümlelerin mantıksal sırası
WHERE ve HAVING'yi bir daha asla karıştırmamak için, hangi sırayı kullandığınızı unutmayın.
SQL bunları zihinsel olarak yürütür:
FROM/JOIN— kaynakları birleştirerek başlangıç tablosunu oluşturur.WHERE— umursamadığınız satırları çıkarır.GROUP BY— kalan satırları gruplar halinde toplar.HAVING— umursamadığınız grupları çıkarır.SELECT— son sütunları (toplamlar dahil) hesaplar.ORDER BY/LIMIT— yeniden sıralayın ve kesin.
Önemli notlar:
WHERE'de yalnızca tablo sütunlarını kullanabilirsiniz;HAVING'de sütunları ve toplamaları gruplandırmayı kullanabilirsiniz.
-- Classic combo: filter first, group, filter the groups, sort.
SELECT d.name, AVG(e.salary) AS average
FROM employees AS e
JOIN departments AS d ON e.department_id = d.id
WHERE e.hired_on >= '2018-01-01' -- filter rows
GROUP BY d.name
HAVING AVG(e.salary) > 35000 -- filter groups
ORDER BY average DESC;Deneyin
Her departman için adı (departmanlar.adı) ve çalışan sayısını gösterin, FAKAT yalnızca en az 2 çalışanı olan departmanlar için. İki sütun, uygun departman başına bir satır.
İpucu göster
HAVING'de 'en az 2' koşulu COUNT(*) >= 2 olur.
3 denemeden sonra çözüm mevcut
Alıştırmayı gözden geçirin
Ortalama maaşı 35.000'i aşan departmanları (departments.name) gösterin. Yalnızca 2018'den itibaren işe alınan çalışanları düşünün. İki sütun: ad ve ortalama. Ortalamaya göre azalan şekilde sıralayın.
İpucu göster
NEREDE satırları filtreler (2018'den itibaren işe alınan çalışanlar), HAVING grupları filtreler (ortalama > 35000).
3 denemeden sonra çözüm mevcut