Lompati ke konten utama
Modul 3 · Pelajaran 4 dari 412/57 dalam kursus~8 min
Pelajaran modul (4/4)

Kelompok penyaringan: MEMILIKI

Setelah Anda mendapatkan hasil per kelompok (pelajaran sebelumnya), Anda sering kali menginginkannya pertahankan hanya grup yang memenuhi syarat: departemen dengan lebih banyak dari 2 orang, proyek dengan anggaran rata-rata di atas 100k, pengguna dengan minimal 10 pesanan. Untuk melakukan ini WHERE tidak cukup.

Mengapa WHERE saja tidak cukup

WHERE memfilter baris tabel, agregasi sebelum. Jadi tidak bisa melihat hasil dari COUNT(*) atau AVG(...): pada saat WHERE berjalan, itu nilai belum dihitung.

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;

Untuk memfilter setelah agregasi, ada klausa khusus: HAVING.

Sintaksnya

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 sama dengan GROUP BY dan WHERE sama dengan FROM: ide yang sama ("filter"), tetapi diterapkan setelah pengelompokan, secara agregat.

Urutan klausa yang logis

Agar tidak bingung lagi WHERE dan HAVING, ingatlah urutannya SQL mengeksekusinya secara mental:

  1. FROM / JOIN — membuat tabel awal dengan menggabungkan sumber.
  2. WHERE — menghapus baris yang tidak Anda pedulikan.
  3. GROUP BY — mengumpulkan baris yang tersisa ke dalam kelompok.
  4. HAVING — menghapus grup yang tidak Anda pedulikan.
  5. SELECT — menghitung kolom akhir (termasuk agregat).
  6. ORDER BY / LIMIT — menyusun ulang dan memotong.

Catatan penting:

  • di WHERE Anda hanya dapat menggunakan kolom tabel;
  • di HAVING Anda dapat menggunakan pengelompokan kolom dan agregat.
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;

Cobalah

Latihan#sql.m3.l4.e1
Upaya: 0Memuat…

Untuk setiap departemen, tampilkan nama (nama departemen) dan jumlah karyawannya, TETAPI hanya untuk departemen yang memiliki minimal 2 karyawan. Dua kolom, satu baris per departemen kualifikasi.

Memuat editor…
Tunjukkan petunjuk

Kondisi 'setidaknya 2' menjadi COUNT(*) >= 2 di HAVING.

Solusi tersedia setelah 3 upaya

Tinjau latihan

Latihan#sql.m3.l4.e2
Upaya: 0Memuat…

Tunjukkan departemen (nama departemen) yang rata-rata gajinya melebihi 35000. Pertimbangkan hanya karyawan yang dipekerjakan mulai tahun 2018 dan seterusnya. Dua kolom: nama dan rata-rata. Urutkan berdasarkan rata-rata menurun.

Memuat editor…
Tunjukkan petunjuk

WHERE memfilter baris (karyawan yang dipekerjakan mulai tahun 2018), HAVING memfilter grup (rata-rata> 35000).

Solusi tersedia setelah 3 upaya