Menghitung Distribusi Kumulatif di SQL (2026)
TL;DR
Distribusi kumulatif di SQL ngitung berapa proporsi baris yang nilainya lebih kecil atau sama dengan nilai tertentu. Cara paling gampang pakai CUME_DIST() OVER (ORDER BY kolom), yang langsung ngasih angka 0 sampai 1. Kalau butuh versi manual, pakai COUNT atau SUM sebagai window function dibagi total baris. Hasilnya berguna buat nyari persentil, ranking relatif, dan ngebandingin satu nilai ke seluruh sebaran data.
Distribusi kumulatif di SQL ngitung berapa proporsi baris yang nilainya lebih kecil atau sama dengan nilai tertentu. Fungsi intinya CUME_DIST().
Pertanyaan yang dia jawab: dari semua transaksi, berapa persen yang nilainya di bawah Rp 50.000? Kalau CUME_DIST buat baris itu 0,72, artinya 72% transaksi nilainya sama atau lebih kecil dari dia.
Di tutorial ini kamu bakal hitung distribusi kumulatif pakai CUME_DIST, bikin versi manualnya sendiri, terus pakai buat nyari persentil dan ranking relatif.
Apa itu distribusi kumulatif?
Distribusi kumulatif adalah proporsi data yang nilainya sampai titik tertentu. Buat tiap nilai, dia jawab: berapa bagian dari seluruh data yang nilainya segini atau lebih rendah? Hasilnya selalu antara 0 dan 1. Baris dengan nilai terkecil dapat angka kecil, baris dengan nilai terbesar dapat 1.
Ini beda dari rata-rata atau total. Distribusi kumulatif ngasih tau posisi satu nilai relatif ke sebaran seluruh data.
Gimana cara hitung pakai CUME_DIST?
CUME_DIST() adalah window function. Dia butuh OVER (ORDER BY kolom) buat tau urutan datanya. Rumus di baliknya: jumlah baris dengan nilai sampai baris ini, dibagi total baris.
SELECT
id_transaksi,
total,
CUME_DIST() OVER (ORDER BY total) AS dist_kumulatif
FROM penjualan
ORDER BY total;
Baris dengan total terkecil dapat angka paling rendah. Baris dengan total terbesar dapat 1, soalnya semua data nilainya sama atau di bawah dia. CUME_DIST adalah salah satu dari keluarga window function di SQL.
Gimana cara bikin versi manualnya?
Kalau database kamu gak punya CUME_DIST, atau kamu mau ngerti cara kerjanya, hitung sendiri pakai COUNT sebagai window function.
SELECT
id_transaksi,
total,
ROUND(
COUNT(*) OVER (ORDER BY total) * 1.0 / COUNT(*) OVER (),
4
) AS dist_kumulatif
FROM penjualan
ORDER BY total;
COUNT(*) OVER (ORDER BY total) ngitung baris dari awal sampai baris sekarang. COUNT(*) OVER () tanpa ORDER BY ngasih total seluruh baris. Bagi keduanya, dapat proporsi kumulatif.
Jangan lupa kaliin 1.0. Tanpa itu, di PostgreSQL pembagian dua bilangan bulat hasilnya dipotong jadi 0.
Gimana cara hitung distribusi kumulatif per grup?
Tambahin PARTITION BY di dalam OVER. Distribusi bakal dihitung ulang buat tiap grup, gak dicampur.
SELECT
kota,
total,
ROUND(CUME_DIST() OVER (PARTITION BY kota ORDER BY total), 4) AS dist_kota
FROM penjualan
ORDER BY kota, total;
Sekarang tiap kota punya sebarannya sendiri. Transaksi Rp 50.000 bisa masuk 40% teratas di kota kecil, tapi cuma 20% teratas di kota besar. Partition yang bikin pemisahan ini jalan.
Contoh kasus: sebaran transaksi toko_berkah
Dataset toko_berkah punya Ngulik Data isinya 8.400 transaksi warung kelontong di Semarang, Januari sampai Maret 2026.
Pemiliknya mau tau: nilai transaksi berapa yang jadi batas 80% transaksi terbawah? Ini buat nentuin ambang "belanja besar".
SELECT total, dist_kumulatif
FROM (
SELECT total,
CUME_DIST() OVER (ORDER BY total) AS dist_kumulatif
FROM penjualan
) t
WHERE dist_kumulatif <= 0.80
ORDER BY dist_kumulatif DESC
LIMIT 1;
Hasilnya: batas 80% ada di Rp 27.500. Artinya 80% transaksi warung ini nilainya di bawah Rp 27.500, dan cuma 20% yang di atas itu.
Angka ini kepakai langsung. Pemiliknya nandain transaksi di atas Rp 27.500 sebagai "pelanggan belanja besar" dan kasih mereka bonus kecil. Batasnya bukan tebakan, tapi dari sebaran data asli.
CUME_DIST vs PERCENT_RANK
Dua fungsi ini mirip tapi beda rumus. Gampang ketuker.
| Fungsi | Rumus | Nilai baris pertama |
|---|---|---|
| CUME_DIST | baris sampai sini / total baris | Lebih dari 0 |
| PERCENT_RANK | (rank - 1) / (total baris - 1) | Tepat 0 |
Pakai CUME_DIST kalau kamu mau tau proporsi data sampai satu nilai. Pakai PERCENT_RANK kalau kamu mau posisi relatif yang mulai dari 0. Buat nyari nilai persentil tertentu, mampir ke cara hitung median dan percentile di SQL.
Kesalahan umum waktu hitung distribusi kumulatif
Lupa ORDER BY di dalam OVER. CUME_DIST butuh urutan biar tau mana yang "lebih kecil". Tanpa ORDER BY, hasilnya jadi 1 buat semua baris.
Pembagian bilangan bulat di versi manual. COUNT(*) / COUNT(*) di kolom integer bisa kepotong jadi 0. Kaliin 1.0 dulu.
Nyaring hasil window function pakai WHERE langsung. Window function dihitung setelah WHERE, jadi kamu gak bisa WHERE CUME_DIST() <= 0.8. Bungkus dulu di subquery, baru filter di luar.
Nyampur banyak grup tanpa PARTITION BY. Kalau data kamu campuran beberapa kota tapi kamu mau sebaran per kota, wajib pakai PARTITION BY. Tanpa itu, semua kota dicampur jadi satu.
FAQ
Apa bedanya distribusi kumulatif sama running total?
Running total ngejumlahin nilai secara bertambah, misalnya omzet hari 1 sampai hari 30. Hasilnya angka rupiah yang makin gede. Distribusi kumulatif ngasih proporsi 0 sampai 1, yaitu berapa bagian data yang nilainya sampai titik tertentu. Running total pakai SUM() OVER, distribusi kumulatif pakai CUME_DIST() atau COUNT dibagi total baris.
Apakah CUME_DIST ada di MySQL?
Ada, mulai MySQL 8.0. Di versi lebih lama, CUME_DIST belum ada, jadi kamu harus hitung manual pakai COUNT sebagai window function. PostgreSQL, BigQuery, Snowflake, dan DuckDB semua udah punya CUME_DIST bawaan. Kalau ragu, versi manual pakai COUNT jalan di hampir semua database yang udah dukung window function.
Gimana cara nyari nilai di persentil tertentu dari distribusi kumulatif?
Bungkus query CUME_DIST di subquery, lalu filter dist_kumulatif di sekitar persentil yang kamu mau. Misalnya buat persentil 80, ambil baris dengan dist_kumulatif paling dekat 0,80. Cara yang lebih langsung pakai PERCENTILE_CONT atau PERCENTILE_DISC kalau database kamu dukung. Buat kebutuhan cepat, subquery CUME_DIST udah cukup akurat.
Kenapa CUME_DIST baris pertama gak nol?
Soalnya CUME_DIST ngitung baris yang nilainya sama atau lebih kecil, termasuk baris itu sendiri. Baris pertama tetap kehitung satu, jadi hasilnya minimal 1 dibagi total baris, bukan nol. Kalau kamu mau angka yang mulai dari nol, pakai PERCENT_RANK. Rumusnya beda: dia ngurangin satu di pembilang, jadi baris pertama dapat tepat nol.
Apakah distribusi kumulatif kena pengaruh nilai duplikat?
Iya. Kalau ada beberapa baris dengan nilai sama, CUME_DIST ngasih angka yang sama buat semuanya, yaitu proporsi sampai kelompok nilai itu selesai. Jadi tiga transaksi Rp 30.000 bakal dapat CUME_DIST identik. Ini perilaku yang bener, soalnya mereka menempati posisi yang sama di sebaran. Kalau kamu butuh urutan unik, pakai ROW_NUMBER sebagai pembeda.
Penutup
Distribusi kumulatif ngasih tau posisi satu nilai relatif ke seluruh data. CUME_DIST() OVER (ORDER BY kolom) ngerjain ini dalam satu baris.
Ingat dua hal: selalu kasih ORDER BY di dalam OVER, dan bungkus di subquery kalau mau nyaring hasilnya.
Cara kerja lengkap fungsi ini ada di dokumentasi window function PostgreSQL.
Semua query di atas udah dites dan siap kamu copy-paste. Lanjut baca cara bikin histogram dan bucket data di SQL buat lihat sebaran data dalam bentuk kelompok.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel terkait
Composite Index di SQL: Cara Kerja dan Urutan Kolom
Composite index itu index atas beberapa kolom sekaligus. Urutan kolomnya nentuin query mana yang kebantu, lewat aturan leftmost prefix.
Menghitung Stickiness (DAU/MAU) di SQL
Stickiness ngukur seberapa sering user balik lagi. Ini cara hitung DAU, MAU, dan rasio stickiness pakai SQL, plus contoh aplikasi UMKM.
Menghitung DAU dan MAU dengan SQL
DAU dan MAU dua metrik wajib buat produk digital. Ini cara hitungnya pakai SQL, lengkap query DISTINCT, per bulan, sampai rasio stickiness.