Menu

GROUP BY dan HAVING di SQLite: Memfilter Hasil Agregasi

Cara GROUP BY mengelompokkan baris di SQLite, dan cara HAVING memfilter kelompok-kelompok itu setelah agregasi, dengan perbedaan WHERE dan HAVING yang dibuat konkret.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

GROUP BY Meringkas Baris ke dalam Kelompok

Fungsi agregat seperti COUNT, SUM, dan AVG meringkas banyak baris menjadi satu angka. GROUP BY memungkinkanmu melakukannya per kategori: satu angka per customer, per bulan, per status. Setiap nilai unik (atau kombinasi nilai) menjadi satu baris di hasil query.

Tiga customer, tiga baris keluar. Enam baris aslinya sudah hilang: semuanya diringkas ke dalam kelompok per customer, dengan COUNT(*) dan SUM(amount) dihitung di dalam masing-masing kelompok.

Gambaran sederhananya: GROUP BY customer berarti "perlakukan semua baris dengan customer yang sama sebagai satu kelompok." Fungsi agregat lalu bekerja pada setiap kelompok secara terpisah.

Apa yang Boleh Ditaruh di Daftar SELECT

Hal ini sering menjebak orang. Saat kamu memakai GROUP BY, setiap kolom di daftar SELECT harus ada di klausa GROUP BY atau berada di dalam fungsi agregat. Kalau tidak, nilainya ambigu: dari baris mana di kelompok itu nilainya harus diambil?

Kalau kamu menulis SELECT region, rep, SUM(amount) dengan GROUP BY region, SQLite tetap akan menjalankannya (SQLite longgar dalam hal ini, sementara database lain menolaknya), tapi rep akan dipilih sembarangan dari kelompok itu. Kamu akan mendapat satu nama rep per region tanpa jaminan yang mana. Jangan mengandalkan itu: kelompokkan berdasarkan setiap kolom tanpa agregat yang kamu tampilkan.

HAVING Memfilter Kelompok Setelah Agregasi

WHERE memfilter baris sebelum pengelompokan. HAVING memfilter kelompok setelah pengelompokan. Itulah seluruh perbedaannya, dan itu sebabnya kamu tidak bisa menaruh COUNT(*) > 1 di klausa WHERE: saat WHERE berjalan, hitungannya belum ada.

Cleo hanya melakukan satu pesanan, jadi kelompoknya tersaring keluar. Ada dan Boris tetap ada. Kondisinya dijalankan terhadap nilai agregat setiap kelompok, bukan terhadap baris satu per satu.

Kamu bisa merujuk alias kolom dari daftar SELECT langsung di HAVING, karena SQLite mengizinkannya:

Cara itu sering lebih mudah dibaca daripada mengulang SUM(amount) di klausa HAVING.

WHERE vs HAVING: Pakai Keduanya Bersamaan

Kedua klausa ini bukan pilihan salah satu. WHERE mempersempit baris mana yang ikut dikelompokkan; HAVING mempersempit kelompok mana yang masuk ke output. Sebagian besar query sungguhan memakai keduanya.

Baca dari atas ke bawah sesuai urutan eksekusinya:

  1. WHERE status = 'paid': buang baris yang di-refund sepenuhnya.
  2. GROUP BY customer: kelompokkan sisanya berdasarkan customer.
  3. SUM(amount) dijalankan per kelompok.
  4. HAVING SUM(amount) > 75: sisakan hanya kelompok yang lolos.

Boris (80 + 20 = 100) dan Cleo (200) bertahan. Satu-satunya pesanan Ada yang dibayar bernilai 50, yang tidak mencapai batasnya.

Banyak Kondisi dan Banyak Kolom Pengelompokan

HAVING menerima operator boolean yang sama dengan WHERE, yaitu AND, OR, NOT, dan kamu bisa mengelompokkan berdasarkan lebih dari satu kolom untuk mendapatkan subkelompok:

Setiap pasangan (region, quarter) adalah kelompok tersendiri. Klausa HAVING mensyaratkan total di atas 100 dan setidaknya dua transaksi. Hanya ('North', 'Q1') dan ('South', 'Q2') yang memenuhi syarat.

Pola Praktis: Mencari Duplikat

Query GROUP BY ... HAVING COUNT(*) > 1 adalah cara standar untuk mencari nilai duplikat di sebuah kolom:

Dua duplikat muncul. Dari sini, biasanya kamu memutuskan apakah akan menggabungkan akun, menambahkan constraint UNIQUE, atau membersihkan data, tapi query untuk menemukannya selalu berbentuk sama.

HAVING Tanpa GROUP BY

Ini tidak lazim tapi sah. Tanpa GROUP BY, seluruh hasil query diperlakukan sebagai satu kelompok, dan HAVING memfilternya secara utuh: kamu mendapat semua nilai agregat atau tidak sama sekali:

Satu baris hasil muncul karena jumlahnya 160. Ubah batasnya menjadi > 200, dan query tidak mengembalikan baris sama sekali. Dalam praktik, kamu hampir selalu memasangkan HAVING dengan GROUP BY, tapi ada baiknya tahu bahwa bahasanya tidak mewajibkan itu.

Rangkuman Singkat

  • GROUP BY meringkas baris ke dalam kelompok per key; fungsi agregat berjalan di dalam setiap kelompok.
  • Setiap kolom tanpa agregat di SELECT sebaiknya muncul di GROUP BY.
  • WHERE memfilter baris sebelum pengelompokan; HAVING memfilter kelompok setelahnya.
  • Fungsi agregat seperti COUNT(*) dan SUM(...) tempatnya di HAVING, tidak pernah di WHERE.
  • HAVING menerima kondisi gabungan dan bisa merujuk alias dari SELECT.

Berikutnya: Foreign Key

Mengagregasi satu tabel itu berguna, tapi sebagian besar skema sungguhan menyebarkan data ke beberapa tabel: pesanan di sini, customer di sana, produk di tempat lain. Foreign key adalah cara menghubungkan tabel-tabel itu agar hubungannya tetap konsisten. Itu bab berikutnya.

Pertanyaan yang sering diajukan

Apa bedanya WHERE dan HAVING di SQLite?

WHERE memfilter baris satu per satu sebelum dikelompokkan. HAVING memfilter kelompok setelah agregasi. Jadi WHERE amount > 100 hanya menyisakan baris yang nilainya di atas 100, sedangkan HAVING SUM(amount) > 100 hanya menyisakan kelompok yang totalnya di atas 100. Fungsi agregat seperti COUNT atau SUM tidak boleh dipakai di WHERE; itulah gunanya HAVING.

Bisakah HAVING dipakai tanpa GROUP BY di SQLite?

Bisa. Tanpa GROUP BY, SQLite memperlakukan seluruh hasil query sebagai satu kelompok, dan HAVING memfilter kelompok itu secara utuh. Query-nya mengembalikan satu baris atau tidak ada baris sama sekali. Dalam praktik, ini jarang terjadi: biasanya kalau ada HAVING, ada juga GROUP BY yang menyertainya.

Bagaimana cara memfilter kelompok berdasarkan COUNT di SQLite?

Taruh fungsi agregatnya di HAVING, bukan di WHERE. Misalnya, SELECT customer_id, COUNT(*) FROM orders GROUP BY customer_id HAVING COUNT(*) > 1 mengembalikan customer yang punya lebih dari satu pesanan. Di SQLite, kamu juga bisa merujuk alias kolom dari daftar SELECT di dalam HAVING.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai