Ana içeriğe geç
Modül 3 · Ders 4 ders 4Kurstaki 12/57~8 min
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.

SQL
-- 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

SQL
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM   table
GROUP BY grouping_column
HAVING   condition_on_aggregate;
SQL
-- 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:

  1. FROM / JOIN — kaynakları birleştirerek başlangıç ​​tablosunu oluşturur.
  2. WHERE — umursamadığınız satırları çıkarır.
  3. GROUP BY — kalan satırları gruplar halinde toplar.
  4. HAVING — umursamadığınız grupları çıkarır.
  5. SELECT — son sütunları (toplamlar dahil) hesaplar.
  6. 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.
SQL
-- 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

Egzersiz#sql.m3.l4.e1
Denemeler: 0Yükleniyor…

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.

Düzenleyici yükleniyor…
İ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

Egzersiz#sql.m3.l4.e2
Denemeler: 0Yükleniyor…

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.

Düzenleyici yükleniyor…
İ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