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.
-- 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
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 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:
FROM/JOIN— membuat tabel awal dengan menggabungkan sumber.WHERE— menghapus baris yang tidak Anda pedulikan.GROUP BY— mengumpulkan baris yang tersisa ke dalam kelompok.HAVING— menghapus grup yang tidak Anda pedulikan.SELECT— menghitung kolom akhir (termasuk agregat).ORDER BY/LIMIT— menyusun ulang dan memotong.
Catatan penting:
- di
WHEREAnda hanya dapat menggunakan kolom tabel; - di
HAVINGAnda dapat menggunakan pengelompokan kolom dan agregat.
-- 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
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.
Tunjukkan petunjuk
Kondisi 'setidaknya 2' menjadi COUNT(*) >= 2 di HAVING.
Solusi tersedia setelah 3 upaya
Tinjau latihan
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.
Tunjukkan petunjuk
WHERE memfilter baris (karyawan yang dipekerjakan mulai tahun 2018), HAVING memfilter grup (rata-rata> 35000).
Solusi tersedia setelah 3 upaya