Analisis Top-N dengan SQL: Produk Terlaris, Customer Terbesar
Kalau kamu kerja sama data penjualan, pasti pernah dapet pertanyaan kayak gini dari tim bisnis: “Produk apa yang paling laris bulan ini?” atau “Siapa 10 customer dengan belanja terbesar?”. Pertanyaan-pertanyaan kayak gini jawabannya bisa didapet lewat teknik yang namanya Top-N Analysis.
Top-N Analysis itu sederhananya adalah cara buat nemuin “N data teratas” dari suatu ukuran tertentu, contohnya top 5 produk terlaris, top 10 customer paling boros, atau top 3 kota dengan penjualan tertinggi. Di SQL, ini bisa dikerjain pakai kombinasi GROUP BY, ORDER BY, LIMIT, sampai Window Function kayak RANK().
💡 Emang Kenapa Sih Perlu Top-N Analysis?
- Bantu tim bisnis fokus ke produk/customer yang paling berdampak.
- Jadi dasar buat keputusan stok, promosi, atau program loyalitas.
- Gampang dijalanin langsung di database, nggak perlu tarik semua data dulu.
- Bisa dikombinasikan sama filter waktu (bulanan, kuartalan, tahunan).
- Salah satu query paling sering muncul di dunia kerja data analyst.
Emang Top-N Analysis Bisa Dipakai buat Apa Aja?
Top-N bukan cuma soal “produk terlaris” doang, tapi konsepnya bisa dipakai ke banyak kasus:
- Nentuin produk terlaris berdasarkan jumlah unit terjual.
- Nentuin produk paling menguntungkan berdasarkan total revenue.
- Nemuin customer dengan total belanja terbesar (biasa disebut VIP customer).
- Ranking cabang/toko dengan performa penjualan terbaik.
- Nyari Top-N per kategori, misalnya produk terlaris di tiap kategori barang.
Top-N Analysis ini sering banget dipakai diam-diam di balik proses berikut:
- Dashboard sales & e-commerce (best seller product)
- Program loyalitas customer (siapa yang dapet reward VIP)
- Laporan bulanan/kuartalan buat manajemen
- Rekomendasi produk berdasarkan tren terlaris
- Analisis performa cabang/toko/sales region
Enaknya Pakai Top-N Query di SQL
- Nggak perlu narik semua data ke aplikasi, cukup query langsung di database.
- Bisa digabung sama filter tanggal, kategori, atau region dengan mudah.
- Kalau pakai Window Function, bisa dapet Top-N per grup sekaligus dalam satu query.
- Hasilnya konsisten dan gampang dijadwalin buat laporan otomatis.
Tapi Ya, Ada Beberapa Hal yang Perlu Diperhatiin
- LIMIT doang kadang nggak adil kalau ada nilai yang sama persis (ties), makanya sering dipasangin sama RANK() atau DENSE_RANK().
- Salah pilih ukuran (quantity vs revenue) bisa ngasih hasil Top-N yang beda jauh maknanya.
- Query bisa lambat kalau tabelnya gede dan belum ada index di kolom yang di-JOIN/GROUP BY.
Kenalan Yuk sama Komponen Penting di Top-N Query
Sebelum praktik, kenalan dulu sama fungsi-fungsi SQL yang bakal sering dipakai:
| Komponen | Artinya |
|---|---|
| GROUP BY | Ngelompokin data berdasarkan kolom tertentu (misal per produk/per customer) |
| SUM() / COUNT() | Ngitung total kuantitas, total revenue, atau jumlah transaksi per grup |
| ORDER BY … DESC | Ngurutin hasil dari yang paling besar ke paling kecil |
| LIMIT N | Ngambil cuma N baris teratas dari hasil yang udah diurutin |
| RANK() / DENSE_RANK() | Window function buat kasih peringkat, termasuk handle data yang nilainya sama (ties) |
| PARTITION BY | Bikin ranking terpisah per grup, misal Top-N per kategori produk |
1. Siapin Tools-nya Dulu
Buat praktik ini, kita pakai SQLite lewat Python (library sqlite3 yang udah bawaan Python) plus pandas biar hasil query-nya gampang dibaca dalam bentuk tabel. Kalau kamu pakai Google Colab, semuanya udah otomatis tersedia, tinggal import aja. Kamu juga bisa pakai tools lain kayak DB Fiddle atau MySQL Workbench kalau lebih terbiasa pakai itu.
Import Library
import sqlite3
import pandas as pd2. Siapin Dataset-nya
Biar praktiknya nyambung sama kasus nyata, kita bikin dataset dummy toko online yang isinya 4 tabel: customers, products, orders, dan order_items. Kode di bawah ini bakal bikin database SQLite langsung di memory (nggak perlu install database beneran).
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.executescript("""
CREATE TABLE customers (
customer_id INTEGER PRIMARY KEY,
customer_name TEXT,
city TEXT
);
CREATE TABLE products (
product_id INTEGER PRIMARY KEY,
product_name TEXT,
category TEXT,
price INTEGER
);
CREATE TABLE orders (
order_id INTEGER PRIMARY KEY,
customer_id INTEGER,
order_date TEXT,
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
CREATE TABLE order_items (
order_item_id INTEGER PRIMARY KEY,
order_id INTEGER,
product_id INTEGER,
quantity INTEGER,
FOREIGN KEY (order_id) REFERENCES orders(order_id),
FOREIGN KEY (product_id) REFERENCES products(product_id)
);
""")
conn.commit()
print("Tabel berhasil dibuat")Kolom yang penting diperhatiin di sini adalah quantity di tabel order_items (buat ngitung unit terjual) dan price di tabel products (buat ngitung revenue).
3. Isi Dataset dengan Data Dummy
Sekarang kita masukin data contohnya. Ada 8 produk dari 3 kategori berbeda, 6 customer, dan beberapa order yang sengaja dibikin biar ada produk dan customer yang jelas-jelas “terlaris”.
cur.executescript("""
INSERT INTO customers (customer_id, customer_name, city) VALUES
(1, 'Andi Saputra', 'Semarang'),
(2, 'Budi Hartono', 'Jakarta'),
(3, 'Citra Dewi', 'Surabaya'),
(4, 'Dian Permata', 'Bandung'),
(5, 'Eka Wijaya', 'Semarang'),
(6, 'Fitri Ramadhani', 'Yogyakarta');
INSERT INTO products (product_id, product_name, category, price) VALUES
(1, 'Kaos Polos', 'Fashion', 75000),
(2, 'Celana Jeans', 'Fashion', 250000),
(3, 'Sepatu Sneakers', 'Fashion', 450000),
(4, 'Mouse Wireless', 'Elektronik', 120000),
(5, 'Keyboard Mekanik', 'Elektronik', 550000),
(6, 'Power Bank', 'Elektronik', 200000),
(7, 'Buku Novel', 'Buku', 85000),
(8, 'Notebook Catatan', 'Buku', 25000);
INSERT INTO orders (order_id, customer_id, order_date) VALUES
(1, 1, '2026-07-02'),
(2, 2, '2026-07-03'),
(3, 3, '2026-07-05'),
(4, 1, '2026-07-08'),
(5, 4, '2026-07-10'),
(6, 5, '2026-07-12'),
(7, 2, '2026-07-15'),
(8, 6, '2026-07-18'),
(9, 3, '2026-07-20'),
(10, 1, '2026-07-25');
INSERT INTO order_items (order_item_id, order_id, product_id, quantity) VALUES
(1, 1, 1, 3),
(2, 1, 4, 1),
(3, 2, 3, 1),
(4, 2, 6, 2),
(5, 3, 1, 5),
(6, 3, 7, 2),
(7, 4, 5, 1),
(8, 4, 4, 2),
(9, 5, 2, 2),
(10, 5, 8, 4),
(11, 6, 1, 10),
(12, 6, 6, 1),
(13, 7, 3, 2),
(14, 7, 5, 1),
(15, 8, 7, 3),
(16, 8, 1, 2),
(17, 9, 4, 3),
(18, 9, 3, 1),
(19, 10, 1, 8),
(20, 10, 6, 2);
""")
conn.commit()
print("Data berhasil diinsert")Biar makin ngerti:
- order_items ini tabel penghubung antara orders dan products, satu order bisa punya banyak item.
- Total unit terjual per produk = SUM(quantity) dari tabel order_items.
- Total revenue = SUM(quantity x price), jadi harus JOIN ke tabel products.
4. Top-N Produk Terlaris Berdasarkan Unit Terjual
Pertanyaan paling dasar: produk mana yang paling banyak terjual unitnya? Kita pakai GROUP BY per produk, jumlahin quantity-nya, urutin dari yang terbesar, terus ambil 5 teratas pakai LIMIT.
Query Top-5 Produk Terlaris (by Unit)
query_top_produk_unit = """
SELECT
p.product_name,
p.category,
SUM(oi.quantity) AS total_unit_terjual
FROM order_items oi
JOIN products p ON oi.product_id = p.product_id
GROUP BY p.product_id, p.product_name, p.category
ORDER BY total_unit_terjual DESC
LIMIT 5;
"""
pd.read_sql_query(query_top_produk_unit, conn)Jalanin kode di atas, hasilnya bakal keluar tabel berisi 5 produk dengan total unit terjual paling banyak.

5. Top-N Produk Terlaris Berdasarkan Revenue
Kadang produk yang unitnya paling banyak terjual belum tentu yang paling nyumbang revenue. Makanya kita perlu itung juga versi revenue-nya, yaitu quantity dikaliin harga.
Query Top-5 Produk Terlaris (by Revenue)
query_top_produk_revenue = """
SELECT
p.product_name,
p.category,
SUM(oi.quantity * p.price) AS total_revenue
FROM order_items oi
JOIN products p ON oi.product_id = p.product_id
GROUP BY p.product_id, p.product_name, p.category
ORDER BY total_revenue DESC
LIMIT 5;
"""
pd.read_sql_query(query_top_produk_revenue, conn)Coba bandingin hasil query ini sama query sebelumnya. Biasanya bakal ada pergeseran ranking karena produk mahal walau unitnya dikit tetep bisa nyumbang revenue gede.
Mau Kuasai Analisis Top-N dengan SQL: Produk Terlaris, Customer Terbesar Sampai Bisa Praktik Langsung?
Materi ini juga kami ajarkan langsung di kelas Edusoft Center, dibimbing mentor, sampai kamu bisa praktik nyata — bukan cuma baca teori.
Tanya Kursus via WhatsApp Lihat contoh project nyata dari siswa kami →

6. Top-N Customer dengan Belanja Terbesar
Sekarang kita pindah fokus ke customer. Query-nya mirip, cuma sekarang kita JOIN tiga tabel sekaligus: customers, orders, dan order_items (plus products buat ambil harga).
Query Top-5 Customer Terbesar
query_top_customer = """
SELECT
c.customer_name,
c.city,
SUM(oi.quantity * p.price) AS total_belanja
FROM order_items oi
JOIN orders o ON oi.order_id = o.order_id
JOIN customers c ON o.customer_id = c.customer_id
JOIN products p ON oi.product_id = p.product_id
GROUP BY c.customer_id, c.customer_name, c.city
ORDER BY total_belanja DESC
LIMIT 5;
"""
pd.read_sql_query(query_top_customer, conn)Hasil query ini biasa dipakai buat nentuin siapa aja customer yang layak masuk program VIP atau dikasih penawaran khusus.

7. Top-N per Kategori Pakai Window Function
Nah, kalau kita mau tau produk terlaris di tiap kategori (bukan cuma top produk secara keseluruhan), LIMIT aja nggak cukup. Di sinilah Window Function kayak RANK() dipakai, dikombinasikan sama PARTITION BY biar ranking-nya dihitung ulang per kategori.
Query Top-2 Produk per Kategori (by Revenue)
query_top_per_kategori = """
WITH revenue_per_produk AS (
SELECT
p.product_name,
p.category,
SUM(oi.quantity * p.price) AS total_revenue
FROM order_items oi
JOIN products p ON oi.product_id = p.product_id
GROUP BY p.product_id, p.product_name, p.category
),
ranked AS (
SELECT
*,
RANK() OVER (
PARTITION BY category
ORDER BY total_revenue DESC
) AS rank_in_category
FROM revenue_per_produk
)
SELECT *
FROM ranked
WHERE rank_in_category <= 2
ORDER BY category, rank_in_category;
"""
pd.read_sql_query(query_top_per_kategori, conn)Biar makin ngerti:
- PARTITION BY category bikin ranking dihitung ulang dari 1 di tiap kategori, bukan ranking global.
- RANK() bakal ngasih peringkat yang sama kalau nilainya sama persis (ties), terus lompat ke peringkat berikutnya.
- DENSE_RANK() mirip RANK(), bedanya nggak ada peringkat yang “dilompatin” walau ada ties.
- ROW_NUMBER() selalu ngasih nomor urut unik, walau nilainya sama persis.

8. Cara Baca Hasil Top-N Analysis
Setelah semua query dijalanin, begini cara bacanya:
- Produk dengan unit terjual tinggi belum tentu penyumbang revenue terbesar, cek dua-duanya.
- Customer di Top-N belanja belum tentu paling sering order, bisa aja cuma sekali beli tapi nominalnya gede.
- Top-N per kategori berguna banget kalau kamu mau evaluasi tiap lini produk secara adil, bukan cuma produk yang paling “populer” secara umum.
- Kalau hasil Top-N-nya kepenuhan produk/customer yang sama terus tiap periode, itu bisa jadi sinyal buat evaluasi strategi produk lain yang kurang laku.
Biar Nggak Lupa, Ini Rangkumannya
| Fungsi | Kegunaan | Contoh |
|---|---|---|
| GROUP BY | Mengelompokkan data per produk/customer sebelum diagregasi. | GROUP BY p.product_id |
| SUM() | Menghitung total quantity atau total revenue per grup. | SUM(oi.quantity * p.price) |
| ORDER BY … DESC LIMIT N | Mengambil N baris teratas setelah data diurutkan. | ORDER BY total_revenue DESC LIMIT 5 |
| RANK() OVER (PARTITION BY …) | Membuat ranking terpisah per grup/kategori. | RANK() OVER (PARTITION BY category ORDER BY total_revenue DESC) |
Kalau Digabung, Alurnya Kayak Gini
⬇
🔗 JOIN Tabel yang Relevan
⬇
📦 GROUP BY per Produk / Customer / Kategori
⬇
📐 Hitung SUM(quantity) atau SUM(quantity x price)
⬇
🔽 ORDER BY … DESC + LIMIT N (atau RANK/PARTITION BY)
⬇
✅ Baca & Validasi Hasil Top-N
📝 Catatan Dikit
Kalau tabel kamu udah gede (jutaan baris), pastiin kolom yang dipakai buat JOIN dan GROUP BY (misalnya product_id, customer_id, order_id) udah punya index. Tanpa index, query Top-N bisa jadi lambat banget karena database harus nyisir semua baris satu-satu.
Abis Ini Belajar Apa Lagi?
🚀 Kalau udah pede sama Top-N Analysis, lanjut aja ke materi-materi ini:
- Window Function lanjutan: LAG(), LEAD(), NTILE()
- Analisis Cohort & Customer Retention pakai SQL
- RFM Analysis (Recency, Frequency, Monetary) buat segmentasi customer
- Time-based Analysis: Top-N per bulan/kuartal
- Optimasi Query dengan Index dan EXPLAIN QUERY PLAN
Materi-materi ini lanjutan yang natural setelah Top-N Analysis, dan sama-sama sering dipakai bareng-bareng di dunia kerja data analyst maupun data engineer.
Penutup
Top-N Analysis itu salah satu skill SQL paling praktis dan paling sering dibutuhin di dunia kerja. Cuma dengan GROUP BY, SUM(), ORDER BY, dan LIMIT, kamu udah bisa jawab pertanyaan bisnis kayak “produk apa yang paling laris” atau “siapa customer paling loyal”.
Kalau kamu udah nyaman sama query dasar ini, coba deh eksplor lebih jauh pakai Window Function biar bisa dapetin insight yang lebih detail, kayak Top-N per kategori atau per periode waktu.
🎉 Keren!
Sekarang kamu udah paham dasar-dasar Top-N Analysis, mulai dari nyari produk terlaris (by unit & revenue), customer terbesar, sampai Top-N per kategori pakai Window Function. Ini modal penting sebelum lanjut ke analisis SQL yang lebih kompleks.
Ditulis oleh Aziz Achmad Juniar
Mau Kuasai Analisis Top-N dengan SQL: Produk Terlaris, Customer Terbesar Sampai Bisa Praktik Langsung?
Materi ini juga kami ajarkan langsung di kelas Edusoft Center, dibimbing mentor, sampai kamu bisa praktik nyata — bukan cuma baca teori.
Tanya Kursus via WhatsApp Lihat contoh project nyata dari siswa kami →
