COUNT(DISTINCT column) menghitung berapa banyak nilai berbeda dalam sebuah kolom: nilai yang muncul sepuluh kali dihitung sekali, dan NULL sama sekali tidak dihitung. Contoh-contohnya berjalan di PostgreSQL, MySQL, SQLite, dan SQL Server.
Cara menggunakan COUNT DISTINCT
Letakkan DISTINCT di dalam COUNT(), di depan kolom atau ekspresi yang ingin dihitung:
COUNT(DISTINCT expression)
Paling mudah dipahami jika dibandingkan dengan dua bentuk COUNT lainnya. COUNT(*) menghitung baris, COUNT(column) menghitung baris yang kolomnya tidak NULL, dan COUNT(DISTINCT column) menghitung nilai non-NULL yang berbeda:
-- Input: orders
-- order_id | customer_id
-- ---------+------------
-- 1 | 1042
-- 2 | 1077
-- 3 | 1042
-- 4 | NULL
SELECT COUNT(*) AS all_rows,
COUNT(customer_id) AS with_customer,
COUNT(DISTINCT customer_id) AS customers
FROM orders;
-- Output:
-- all_rows | with_customer | customers
-- ---------+---------------+----------
-- 4 | 3 | 2
Empat pesanan berasal dari dua pelanggan: 1042 memesan dua kali, dan pesanan 4 tidak punya pelanggan sama sekali.
Aturan yang perlu diketahui
- NULL tidak dihitung. Jika nilai yang kosong perlu dihitung sebagai satu nilai tambahan, tambahkan sendiri:
-- Input: the orders table above
SELECT COUNT(DISTINCT customer_id)
+ MAX(CASE WHEN customer_id IS NULL THEN 1 ELSE 0 END) AS customers_and_guests
FROM orders;
-- Output: 3
-
MySQL dan SQL Server mengabaikan huruf besar/kecil secara default, sehingga
'SQL'dan'sql'dihitung sebagai satu nilai. HitungLOWER(tag)jika huruf besar/kecil tidak penting:
-- Input: tags
-- post_id | tag
-- --------+---------
-- 1 | SQL
-- 2 | sql
-- 3 | Postgres
SELECT COUNT(DISTINCT tag) FROM tags;
-- Output: 3 (2 in MySQL and SQL Server)
SELECT COUNT(DISTINCT LOWER(tag)) FROM tags;
-- Output: 2
-
DISTINCT juga bisa dipakai di dalam
SUMdanAVG, tetapi yang dibuang adalah nilai berulang, bukan baris berulang. Dua produk berbeda dengan harga yang sama hanya dijumlahkan sekali:
-- Input: order_lines
-- product | price
-- ---------+------
-- Pen | 2.00
-- Pencil | 2.00
-- Notebook | 5.00
SELECT SUM(price) AS total, SUM(DISTINCT price) AS distinct_total FROM order_lines;
-- Output:
-- total | distinct_total
-- ------+---------------
-- 9.00 | 7.00
Sintaks alternatif
COUNT(DISTINCT ...) hanya menerima satu kolom. Untuk menghitung kombinasi berbeda dari beberapa kolom, hitung baris dari subquery DISTINCT. PostgreSQL dan MySQL juga punya cara singkat:
-- Input: orders
-- order_id | customer_id | product_id
-- ---------+-------------+-----------
-- 1 | 1 | 23
-- 2 | 12 | 3
-- 3 | 1 | 23
-- 4 | 12 | 5
SELECT COUNT(*) FROM (SELECT DISTINCT customer_id, product_id FROM orders) AS pairs;
-- Output: 3
-- PostgreSQL
SELECT COUNT(DISTINCT (customer_id, product_id)) FROM orders;
-- Output: 3
-- MySQL
SELECT COUNT(DISTINCT customer_id, product_id) FROM orders;
-- Output: 3
Anda juga akan melihat kolom-kolom digabung menjadi satu string dengan CONCAT(). Cara ini butuh pemisah: tanpa pemisah, pelanggan 1 dengan produk 23 dan pelanggan 12 dengan produk 3 sama-sama menjadi '123':
-- Input: the orders table above
SELECT COUNT(DISTINCT CONCAT(customer_id, product_id)) FROM orders;
-- Output: 2
SELECT COUNT(DISTINCT CONCAT(customer_id, '_', product_id)) FROM orders;
-- Output: 3
Hitungan distinct yang eksak harus mengurutkan atau melakukan hash pada setiap nilai, sehingga menjadi lambat pada tabel yang sangat besar. SQL Server punya APPROX_COUNT_DISTINCT(), yang lebih cepat dan selisihnya tetap dalam 2% dari hitungan eksak pada 97% kasus:
-- SQL Server
-- Input: the orders table above
SELECT APPROX_COUNT_DISTINCT(customer_id) AS customers FROM orders;
-- Output: 2
Kapan sebaiknya menggunakan COUNT DISTINCT?
Gunakan COUNT DISTINCT jika pertanyaannya adalah “berapa banyak … yang berbeda?” dan bukan “berapa banyak baris?”. Sebagian besar pertanyaan semacam itu termasuk dalam salah satu dari empat kategori berikut.
Menghitung pengunjung, pelanggan, atau produk unik
Log kunjungan, pesanan, atau penjualan mencatat pengunjung, pelanggan, atau produk yang sama berulang kali. COUNT DISTINCT pada ID-nya mengubah baris-baris itu menjadi jumlah individu.
Menghitung nilai unik di setiap grup
Tambahkan GROUP BY dan Anda mendapatkan satu hitungan distinct per grup: jumlah siswa berbeda per kursus, produk berbeda per vendor, pelanggan berbeda per bulan.
Menghitung kombinasi kolom yang unik
Terkadang dua baris baru dianggap “sama” jika dua kolom sama-sama cocok: pengguna yang sama dengan jenis masalah yang sama, atau rute yang sama antara dua bandara. Hitung kombinasinya dengan salah satu bentuk multi-kolom di bagian “Sintaks alternatif”.
Menghitung nilai unik yang memenuhi suatu kondisi
Letakkan ekspresi CASE di dalam COUNT(DISTINCT ...) untuk menghitung hanya sebagian baris. CASE mengembalikan NULL untuk baris yang tidak Anda inginkan, dan NULL tidak dihitung, sehingga satu query bisa menghasilkan beberapa hitungan terfilter berdampingan.
Contoh nyata COUNT DISTINCT
Pengguna aktif bulanan
Hitung pengguna yang melakukan aktivitas apa pun di bulan September, berapa kali pun mereka kembali:
-- Input: events
-- event_id | user_id | event_date
-- ---------+---------+-----------
-- 1 | 301 | 2026-08-30
-- 2 | 302 | 2026-09-02
-- 3 | 302 | 2026-09-15
-- 4 | 305 | 2026-09-21
-- 5 | 302 | 2026-10-01
SELECT COUNT(DISTINCT user_id) AS active_users
FROM events
WHERE event_date >= '2026-09-01' AND event_date < '2026-10-01';
-- Output: 2
Produk yang dijual setiap vendor
COUNT(*) memberikan jumlah penjualan setiap vendor, dan COUNT(DISTINCT product) berapa banyak produk berbeda yang tercakup dalam penjualan itu:
-- Input: sales
-- vendor | product | color
-- -----------+----------+------
-- Acme | Mug | Red
-- Acme | Mug | Blue
-- Acme | Mug | Red
-- Acme | Tote Bag | Red
-- Brightside | Notebook | Black
SELECT vendor, COUNT(*) AS sales, COUNT(DISTINCT product) AS products
FROM sales
GROUP BY vendor;
-- Output:
-- vendor | sales | products
-- -----------+-------+---------
-- Acme | 4 | 2
-- Brightside | 1 | 1
Rute yang diterbangi maskapai
Sebuah rute adalah gabungan asal dan tujuan. Dua penerbangan dari LHR ke JFK adalah satu rute, tetapi JFK ke LHR adalah rute lain:
-- Input: flights
-- flight_no | origin | destination
-- ----------+--------+------------
-- 101 | LHR | JFK
-- 105 | LHR | JFK
-- 102 | JFK | LHR
-- 301 | LHR | LAX
SELECT COUNT(*) AS routes
FROM (SELECT DISTINCT origin, destination FROM flights) AS r;
-- Output: 3
Pelanggan berdasarkan harga barang yang dibeli
Hitung pelanggan yang membeli produk 100 sampai 200, lalu kelompokkan berdasarkan harga pesanan mereka. Pelanggan 7 membuat dua pesanan murah tetapi dihitung sekali, dan produk pelanggan 15 berada di luar rentang:
-- Input: orders
-- order_id | customer_id | product_id | price
-- ---------+-------------+------------+-------
-- 1 | 7 | 105 | 25.00
-- 2 | 7 | 142 | 40.00
-- 3 | 9 | 150 | 120.00
-- 4 | 12 | 188 | 310.00
-- 5 | 15 | 260 | 30.00
SELECT
COUNT(DISTINCT customer_id) AS customers,
COUNT(DISTINCT CASE WHEN price BETWEEN 1 AND 50 THEN customer_id END) AS low_spenders,
COUNT(DISTINCT CASE WHEN price BETWEEN 51 AND 150 THEN customer_id END) AS mid_spenders,
COUNT(DISTINCT CASE WHEN price > 150 THEN customer_id END) AS high_spenders
FROM orders
WHERE product_id BETWEEN 100 AND 200;
-- Output:
-- customers | low_spenders | mid_spenders | high_spenders
-- ----------+--------------+--------------+--------------
-- 3 | 1 | 1 | 1
Pelanggan yang memiliki pesanan di dua rentang harga dihitung di keduanya.
Bacaan lanjutan tentang COUNT DISTINCT
Di blog ini:
-
Panduan SQL GROUP BY:
COUNT,SUM, danAVGuntuk setiap grup - Panduan mencari duplikat di SQL: temukan nilai yang muncul lebih dari sekali
- Panduan menghapus duplikat di SQL: hapus salinan yang berlebih
- Panduan pernyataan SQL CASE: kondisi di balik hitungan bersyarat
-
Having vs Where di SQL: filter berdasarkan hitungan dengan
HAVING - Cheat sheet SQL: fungsi agregat dan SQL lainnya dalam satu halaman
Dokumentasi resmi:
- PostgreSQL: ekspresi agregat
- MySQL: COUNT(DISTINCT)
- SQLite: count()
- SQL Server: COUNT dan APPROX_COUNT_DISTINCT
Beekeeper Studio Adalah GUI Database Gratis & Open Source
Tool query & editor SQL terbaik yang pernah saya pakai. Semua yang saya butuhkan untuk mengelola database ada di sini. - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studio cepat, intuitif, dan mudah digunakan. Beekeeper mendukung banyak sekali database, dan berjalan mulus di Windows, Mac, dan Linux.
Apa Kata Pengguna Tentang Beekeeper Studio
"Beekeeper Studio sepenuhnya menggantikan alur kerja SQL lama saya. Cepat, intuitif, dan membuat pekerjaan database kembali menyenangkan."
"Saya sudah mencoba banyak GUI database, tetapi Beekeeper punya keseimbangan sempurna antara fitur dan kesederhanaan. Langsung jalan."