Kursus
WHERE dan HAVING adalah dua klausa penting dalam SQL. Baik saat Anda menulis kueri yang sangat canggih maupun yang sangat sederhana, Anda akan menemui kebutuhan untuk menggunakan keduanya. Anda bisa menganggap WHERE dan HAVING sebagai saudara. Keduanya berfungsi serupa (penyaringan), dan sering muncul bersama. Namun, seperti saudara, keduanya memiliki karakteristik dan peran yang berbeda.
Jika Anda sedang mempelajari perbedaan WHERE dan HAVING, saya sarankan mendaftar ke jalur keterampilan SQL Fundamentals kami sebagai titik awal yang komprehensif. Di sana Anda akan mempelajari berbagai klausa SQL, urutan eksekusi klausa SQL, pengoptimalan kueri SQL, dan banyak hal penting lainnya.
Jawaban Singkat: WHERE vs. HAVING
Inti masalah—dan sumber kebingungan bagi banyak orang—adalah WHERE bekerja pada data tingkat baris, sedangkan HAVING beroperasi pada data yang telah dikelompokkan. Berikut pedomannya:
-
WHEREmenyaring baris sebelum proses pengelompokan atau agregasi apa pun terjadi. Ini berlaku pada baris individual dan tidak dapat digunakan dengan fungsi agregat. -
HAVINGmenyaring grup setelah pengelompokan dan agregasi dilakukan. Ini berlaku pada hasil fungsi agregat dan digunakan bersama denganGROUP BY.
Contoh singkat untuk menunjukkan perbedaannya
Mari lihat contoh cepat. Jika Anda ingin mengikuti dengan alur kerja sendiri, Anda dapat mengunduh dataset sewa properti dari repositori GitHub ini.
Sekarang, misalkan kita perlu menampilkan semua properti dalam dataset yang memiliki harga sewa kurang dari $500. Tingkat detail setiap baris dalam dataset (satu properti per baris) sesuai dengan tingkat detail kondisi kueri. Oleh karena itu, kita menggunakan WHERE dalam kueri berikut:
SELECT *
FROM rentals
WHERE rental_price < 500
Hasilnya akan terlihat seperti ini. Perhatikan bahwa ada 118 baris yang dikembalikan.

Penyaringan baris sederhana dengan WHERE. Gambar oleh Penulis.
Sekarang, misalkan kita tidak ingin membuat tabel properti, melainkan tabel kota yang memiliki harga sewa rata-rata kurang dari $2.700. Alih-alih tiap baris merepresentasikan properti, kita akan mengelompokkan baris dan melakukan agregasi harga sewa menjadi harga sewa rata-rata untuk tiap kota. Oleh karena itu, kita akan menggunakan HAVING, seperti pada kueri berikut:
SELECT city, AVG(rental_price) AS average_rent
FROM rentals
GROUP BY city
HAVING AVG(rental_price) < 2700;
Dan hasilnya akan seperti ini. Perhatikan hanya ada satu hasil.

Penyaringan grup sederhana dengan HAVING. Gambar oleh Penulis.
WHERE, HAVING, dan Urutan Eksekusi SQL
Kita melihat bahwa WHERE digunakan untuk penyaringan tingkat baris, sedangkan HAVING untuk penyaringan tingkat agregat. Memahami perbedaan ini juga membuka jalan bagi kita untuk mempelajari urutan eksekusi klausa SQL.
WHERE dievaluasi sebelum GROUP BY, dan tepat setelah FROM (serta JOIN jika ada); ia tidak dapat menangani pengelompokan atau agregasi apa pun. WHERE berlaku sebelum agregasi dilakukan. Itulah mengapa ia hanya beroperasi pada data tingkat baris.
Sementara itu, HAVING muncul setelah eksekusi klausa GROUP BY. Artinya, ia berlaku setelah tabel ditransformasi dan dikelompokkan pada tingkat yang berbeda dari tingkat granularitas tabel sumber. HAVING beroperasi pada versi tabel yang baru dan telah ditransformasi.
Cara Menggunakan Klausa WHERE dalam SQL
Mari mundur selangkah dan melihat masing-masing klausa secara terpisah. Kita mulai dengan klausa WHERE.
Sintaks dan pernyataan WHERE
WHERE dapat digunakan dalam tiga pernyataan SQL yang berbeda: SELECT, UPDATE, dan DELETE.
WHERE dalam pernyataan SELECT
Dalam pernyataan SELECT, yang digunakan untuk mengambil data dari basis data, WHERE berperan langsung dalam penyaringan tingkat baris dan memiliki posisi yang dikenal tepat setelah klausa FROM, seperti terlihat pada kueri berikut:
SELECT column1, column2… etc.
FROM table_name
WHERE condition;
WHERE yang digunakan dengan SELECT adalah konteks di mana klausa WHERE paling sering tertukar dengan HAVING.
WHERE dalam pernyataan UPDATE
Selain itu, WHERE berperan penting dalam pernyataan UPDATE untuk menentukan baris tempat pembaruan data harus dilakukan, seperti terlihat pada sintaks berikut:
UPDATE table_name
SET column_name1 = value1, column_name2 = value2… etc.
WHERE condition;
WHERE dalam pernyataan DELETE
WHERE juga berguna dalam pernyataan DELETE untuk menentukan rekaman (baris) yang harus dihapus, seperti terlihat di sini:
DELETE FROM table_name
WHERE condition;
Cara menulis kondisi WHERE
Kondisi WHERE ditulis sebagai ekspresi logis sederhana. Terdiri dari tiga bagian: variabel/operan, kondisi, dan nilai/hasil. Mari lihat opsi untuk kondisi WHERE yang mencakup operator perbandingan dan logika.
| Tanda operator | Deskripsi | Tipe data operan |
|---|---|---|
| = | Sama dengan (pada tanggal) | Numerik, Teks, Tanggal/stempel waktu, Boolean |
| < | Kurang dari (sebelum tanggal) | Numerik, Tanggal/stempel waktu |
| > | Lebih besar dari (setelah tanggal) | Numerik, Tanggal/stempel waktu |
| <= | Kurang dari atau sama dengan (pada atau sebelum tanggal) | Numerik, Tanggal/stempel waktu |
| >= | Lebih besar dari atau sama dengan (pada atau setelah tanggal) | Numerik, Tanggal/stempel waktu |
| <> (!=) | Tidak sama dengan (tidak pada tanggal) | Numerik, Teks, Tanggal/stempel waktu, Boolean |
| IN | Sama dengan lebih dari satu nilai (pada banyak tanggal) | Numerik, Teks, Tanggal/stempel waktu, Boolean (meski kurang masuk akal!) |
| LIKE | Mencocokkan pola teks (menggunakan wildcard) | Teks |
| BETWEEN | Berada dalam suatu rentang | Numerik, Tanggal/stempel waktu |
| AND | Menggabungkan beberapa kondisi, semuanya harus benar | Logika (Boolean) |
| OR | Menggabungkan beberapa kondisi, minimal satu harus benar | Logika (Boolean) |
| NOT | Mengingkari suatu kondisi | Logika (Boolean) |
| IS NULL | Memeriksa nilai null | Semua tipe data |
| IS NOT NULL | Memeriksa nilai non-null | Semua tipe data |
Berikut contoh saat kita menggunakan NOT bersama operator perbandingan IN:
SELECT *
FROM rentals
WHERE city NOT IN ('Cairo', 'Giza');
Pernyataan ini akan mengembalikan semua properti yang tidak berada di kota Cairo maupun Giza.

Properti di luar Cairo dan Giza. Gambar oleh Penulis.
Kasus penggunaan WHERE
Mengetahui bahwa WHERE beroperasi dengan pernyataan SELECT, UPDATE, dan DELETE, kita dapat memperkirakan tiga kasus penggunaan: penyaringan tingkat baris, pengambilan data, dan manipulasi data.
Penyaringan tingkat baris
Kita dapat menyaring baris tabel berdasarkan satu atau lebih kondisi. Kueri berikut menyaring baris untuk hanya menyertakan properti vila.
SELECT *
FROM rentals
WHERE type = ‘villa’;

Memilih properti vila. Gambar oleh Penulis.
Pengambilan data
WHERE dapat digunakan untuk mengambil titik data spesifik yang kita cari. Ini mirip dengan penyaringan tingkat baris namun lebih spesifik. Misalkan kita perlu mengetahui ID properti yang tersedia pada 1 Januari 2022 di Cairo, kita dapat menggunakan kueri berikut:
SELECT property_id
FROM rentals
WHERE available_date = '2022-01-01'
AND city = 'Cairo';

Mengambil satu titik data. Gambar oleh Penulis.
Manipulasi data
Terakhir, WHERE sangat membantu untuk mengubah nilai dan menghapus rekaman tertentu di basis data Anda. Misalnya, jika diketahui bahwa properti 171 sebenarnya tidak ramah hewan peliharaan, kita dapat mengubah kolom pet_friendly menggunakan WHERE dalam pernyataan UPDATE sebagai berikut:
UPDATE rentals
SET pet_friendly = false
WHERE property_id = 171;
Cara Menggunakan Klausa HAVING dalam SQL
Sekarang saatnya beralih ke klausa HAVING dengan tingkat detail yang sama.
Sintaks dan pernyataan HAVING
Pertama-tama, kita perlu tahu bahwa klausa HAVING hanya dapat digunakan dalam pernyataan SELECT. Oleh karena itu, satu-satunya sintaks yang dimilikinya adalah sebagai berikut:
SELECT grouped_column, aggregate_function(aggregated_column)… etc.
FROM table_name
GROUP BY grouped_column
HAVING condition
Perhatikan bahwa Anda dapat menambahkan lebih dari satu kolom pengelompokan dan lebih dari satu kolom agregat. Kita akan melihat contohnya di bawah.
Cara menulis kondisi HAVING
Seperti WHERE, kondisi HAVING ditulis sebagai ekspresi logis tetapi dengan satu komponen tambahan, yaitu fungsi agregasi. Jadi, kondisi HAVING terdiri dari 1) Fungsi agregat, 2) variabel/operan, 3) Operator perbandingan, dan 4) nilai/hasil.
Fungsi agregat dengan HAVING
SQL pada dasarnya memiliki lima fungsi agregat, plus satu fungsi keenam yang merupakan kasus khusus. Fungsi-fungsi tersebut adalah:
| Fungsi agregat | Tipe data yang sesuai |
|---|---|
| SUM() | Numerik |
| AVG() | Numerik |
| MIN() | Numerik, Teks, Tanggal/stempel waktu |
| MAX() | Numerik, Teks, Tanggal/stempel waktu |
| COUNT() | Numerik, Teks, Tanggal/stempel waktu, Boolean |
Mari coba satu contoh. Di sini, kita menggunakan fungsi COUNT() dengan GROUP BY untuk membuat tabel frekuensi, dan menggunakan kondisi HAVING sebagai filter. Secara spesifik, kita perlu mengetahui kota-kota yang disebutkan 150 kali atau kurang, yang dalam konteks ini terkait dengan jumlah pendaftaran. Kita bisa menggunakan kueri berikut:
SELECT city, COUNT(*) AS properties_count
FROM rentals
GROUP BY city
HAVING COUNT(*) <= 150;

Menggunakan COUNT() dengan HAVING. Gambar oleh Penulis.
Operator perbandingan dan logika
HAVING menerima semua operator perbandingan dan logika yang diterima oleh WHERE. Satu-satunya perbedaan adalah tipe data yang sesuai pada HAVING terutama bergantung pada fungsi agregat, seperti terlihat pada tabel di atas.
Kasus penggunaan HAVING
Berbeda dengan WHERE, HAVING tidak dapat digunakan dalam pernyataan UPDATE dan DELETE; HAVING hanya digunakan untuk pengambilan data. Secara garis besar, ini berarti dua skenario:
Penyaringan tingkat grup
Ini adalah penggunaan umum dan wajar dari HAVING. Salah satu contohnya adalah hanya mengembalikan kota-kota yang memiliki harga sewa rata-rata di bawah $2.700.
SELECT city, AVG(rental_price) AS avg_price
FROM rentals
GROUP BY city
HAVING AVG(rental_price) < 2700;
Penyaringan satu baris
Ini kasus yang tidak umum, tetapi HAVING dapat digunakan untuk mengembalikan agregasi satu baris, seperti metrik atau KPI, hanya jika memenuhi kondisi tertentu. Ini dapat dilakukan dengan menggunakan HAVING tanpa GROUP BY. Pada contoh berikut, kita mengembalikan harga sewa rata-rata hanya jika di bawah $2.800. Jika ukurannya memenuhi kondisi, kita akan mendapatkan hasil satu baris. Jika tidak, tabel akan kosong.
SELECT AVG(rental_price) as avg_price
FROM rentals
HAVING AVG(rental_price) > 2800;
Mengombinasikan WHERE dan HAVING
WHERE dan HAVING dapat dikombinasikan untuk menyaring tabel sebelum dan sesudah agregasi. Pada contoh berikut, kita mengembalikan jumlah properti di setiap kota, hanya menghitung properti yang ramah hewan peliharaan, dan memfilter hanya kota yang memiliki lebih dari 80 properti.
SELECT city, COUNT(*) AS number_properties
FROM rentals
WHERE pet_friendly = true
GROUP BY city
HAVING COUNT(*) > 80;

Kombinasi dasar WHERE dan HAVING. Gambar oleh Penulis.
Perbedaan WHERE dan HAVING dalam Kinerja
Kita tahu bahwa klausa WHERE diterapkan sebelum pengelompokan atau agregasi. Kita juga harus tahu bahwa, karena alasan ini—karena mengurangi jumlah baris yang diproses lebih awal dalam kueri—WHERE lebih efisien untuk menyaring baris individual.
Di sisi lain, klausa HAVING diterapkan setelah agregasi dan menyaring himpunan hasil berdasarkan data yang dikelompokkan. Karena memproses data setelah semua baris dikelompokkan, secara umum ini kurang efisien dibanding WHERE, meskipun tetap diperlukan untuk kondisi yang melibatkan fungsi agregat.
Mari lihat kueri berikut:
SELECT city, COUNT(*)
FROM rentals
GROUP BY city
HAVING rental_price < 2700;
Kueri ini tidak efisien karena kondisi rental_price tidak bergantung pada agregasi—ia menyaring baris individual. Kueri ini akan terlebih dahulu mengelompokkan semua sewaan berdasarkan kota, menghitungnya, lalu baru menyaring hasil, yang tidak efisien karena memproses baris yang tidak perlu. Karena itu, kueri berikut akan lebih cepat:
SELECT city, COUNT(*)
FROM rentals
WHERE rental_price < 2700
GROUP BY city;
Tips optimasi WHERE dan HAVING
Berdasarkan hal di atas, kita dapat melihat beberapa praktik baik yang dapat mengoptimalkan penggunaan klausa WHERE dan HAVING. Ini penting jika Anda memiliki dataset besar.
-
Sangat Selektif: Saring sesuai nilai yang benar-benar Anda perlukan dan tidak lebih. Ini akan membantu mengurangi jumlah baris dalam tampilan, sehingga meningkatkan efisiensi kueri.
-
Sederhana: Hilangkan kondisi, agregasi, dan type cast yang tidak perlu. Semua tambahan ini pasti memiliki biaya komputasi.
-
Saring Lebih Awal: Jika Anda melakukan agregasi tingkat grup, pra-saring baris dengan
WHEREuntuk mempercepat proses pengelompokan. Dengan begitu, Anda mengurangi jumlah baris yang perlu diproses saat pengelompokan.
Tabel perbandingan
Ringkaslah poin-poin kita ke dalam tabel berikut:
| Perbandingan | WHERE | HAVING |
|---|---|---|
| Tujuan utama | Penyaringan tingkat baris | Penyaringan tingkat grup |
| Sintaks dasar | SELECT column1, column2... FROM table_name WHERE condition; | SELECT grouped_column, aggregate_function(aggregated_column)... FROM table_name GROUP BY grouped_column HAVING condition; |
| Urutan evaluasi | Sebelum GROUP BY | Setelah GROUP BY |
| Pernyataan yang kompatibel | SELECT, UPDATE, DELETE | SELECT |
| Kondisi | Tidak dapat menyertakan fungsi agregat | Harus melibatkan fungsi agregat |
| Kasus penggunaan | Penyaringan tingkat baris Pengambilan data Manipulasi data | Penyaringan tingkat grup Penyaringan satu baris |
| Subkueri | Dapat bekerja dengan subkueri | Harus ditulis sebagai CTE |
Kesimpulan
Sepanjang artikel, kita membahas perbedaan utama antara WHERE dan HAVING dalam SQL, yaitu bahwa WHERE menyaring baris sebelum agregasi, sedangkan HAVING menyaring data yang dikelompokkan setelah agregasi. Kita juga membahas beberapa perbedaan yang kurang dikenal, seperti fakta bahwa WHERE dapat digunakan dengan pernyataan SELECT, UPDATE, dan DELETE, sementara HAVING hanya bekerja dengan SELECT. Kita juga sedikit menyinggung soal kinerja.
SQL Basics Cheat Sheet dari DataCamp memberikan rangkuman yang baik tentang klausa WHERE dan HAVING, serta panduan tentang cara melakukan penyaringan di SQL. Jika Anda baru memulai dengan SQL, Anda juga perlu melihat jalur keterampilan SQL Fundamentals dan jalur karier Associate Data Analyst in SQL.

Islam adalah konsultan data di The KPI Institute. Dengan latar belakang jurnalisme, Islam memiliki minat yang beragam, termasuk menulis, filsafat, media, teknologi, dan budaya.
Frequently Asked Questions
Apa perbedaan antara WHERE dan HAVING?
WHERE melakukan penyaringan tingkat baris, sedangkan HAVING melakukan penyaringan tingkat grup.
Bisakah saya mengombinasikan WHERE dan HAVING dalam satu kueri?
Ya, dan sangat disarankan untuk menggunakan WHERE jika Anda akan menggunakan HAVING.
Dapatkah WHERE bekerja dengan fungsi agregat seperti HAVING?
Tidak, hanya HAVING yang dapat bekerja dengan fungsi agregat.
Apakah WHERE dan HAVING bekerja dengan operator perbandingan dan logika yang sama?
Ya, keduanya bekerja dengan operator yang sama karena kondisi WHERE dan HAVING ditulis sebagai ekspresi logis.
Bisakah saya menggunakan HAVING tanpa GROUP BY?
HAVING umumnya digunakan setelah pengelompokan dengan GROUP BY. Satu pengecualian adalah penyaringan tampilan satu nilai (seperti menghitung satu metrik).
