Sessionization SQL: Kelompokkan Event Jadi Sesi Pengguna
TL;DR
Sessionization SQL adalah teknik ngelompokkan event berurutan dari satu user jadi sesi, berdasarkan jeda waktu antar event. Caranya: pakai LAG buat ambil timestamp event sebelumnya, tandai event yang jedanya lewat ambang batas (umumnya 30 menit) sebagai awal sesi baru, lalu SUM kumulatif penanda itu buat bikin session_id. Hasilnya bisa dipakai ngitung durasi sesi, event per sesi, dan sesi per user.
Sessionization SQL adalah teknik ngelompokkan event berurutan dari satu user jadi sesi, berdasarkan jeda waktu antar event.
Masalahnya gini. Log event kamu isinya ribuan baris: user 88 buka halaman produk jam 09:14, klik keranjang 09:16, terus muncul lagi jam 20:41. Itu satu sesi atau dua?
Dua. Dan SQL nggak tau itu sampai kamu yang kasih tau aturannya.
Apa itu sessionization dan kapan dibutuhkan?
Sessionization ngasih nomor sesi ke tiap baris event, dengan aturan: kalau jeda dari event sebelumnya lewat ambang batas tertentu, event itu jadi awal sesi baru.
Kamu butuh ini kalau mau jawab pertanyaan kayak:
- Rata-rata satu kunjungan berapa lama?
- Berapa halaman yang dibuka per kunjungan?
- Berapa persen sesi yang berakhir dengan pembelian?
Tanpa sesi, kamu cuma bisa ngitung total event dan total user. Dua angka yang nggak ngasih tau apa-apa soal perilaku.
Kenapa ambang batasnya 30 menit?
Angka 30 menit warisan Google Analytics, dan udah jadi standar de facto. Tapi itu bukan hukum alam.
Buat aplikasi ojek online yang dipakai cepat, 15 menit lebih masuk akal. Buat marketplace yang orang suka bandingin harga sambil ngerjain hal lain, 60 menit lebih realistis.
Cara nentuinnya: lihat distribusi jeda antar event, cari titik di mana jumlah jeda mulai anjlok. Itu batas alaminya.
Gimana bikin session_id di SQL?
Tiga langkah. Semuanya pakai window function.
Langkah 1: Ambil waktu event sebelumnya pakai LAG
SELECT user_id,
waktu,
halaman,
LAG(waktu) OVER (PARTITION BY user_id ORDER BY waktu) AS waktu_sebelumnya
FROM event_log;
LAG ngambil nilai dari baris sebelumnya. PARTITION BY user_id bikin perhitungannya reset tiap ganti user — event user lain nggak nyampur. Detail cara kerjanya ada di halaman fungsi LAG.
Event pertama tiap user bakal punya waktu_sebelumnya = NULL. Itu wajar, dan nanti kita perlakuin sebagai awal sesi.
Langkah 2: Tandai awal sesi baru
WITH dengan_lag AS (
SELECT user_id, waktu, halaman,
LAG(waktu) OVER (PARTITION BY user_id ORDER BY waktu) AS waktu_sebelumnya
FROM event_log
)
SELECT user_id, waktu, halaman,
CASE
WHEN waktu_sebelumnya IS NULL THEN 1
WHEN waktu - waktu_sebelumnya > INTERVAL '30 minutes' THEN 1
ELSE 0
END AS awal_sesi
FROM dengan_lag;
Sekarang tiap baris punya flag 1 atau 0. Angka 1 artinya "di sini sesi baru dimulai".
Langkah 3: SUM kumulatif buat bikin nomor sesi
Ini bagian yang bikin orang mikir agak lama pas pertama lihat.
SELECT user_id, waktu, halaman,
SUM(awal_sesi) OVER (
PARTITION BY user_id
ORDER BY waktu
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS nomor_sesi
FROM ditandai;
SUM kumulatif ngejumlahin flag dari baris pertama sampai baris sekarang. Selama flagnya 0, jumlahnya nggak berubah — jadi event-event itu dapat nomor sesi yang sama. Begitu ketemu flag 1, jumlahnya naik satu, dan sesi baru dimulai.
Hasilnya: event 1, 2, 3 dapat nomor sesi 1. Event 4 (yang jedanya 11 jam) dapat nomor sesi 2. Persis yang kita mau.
Contoh kasus: klik pengguna toko_berkah online
Dataset event_log dari toko online toko_berkah: 62.400 event dari 4.180 user selama Maret 2026.
Contoh baris mentah buat user 88:
user_id waktu halaman
88 2026-03-14 09:14:02 /produk/beras-5kg
88 2026-03-14 09:16:41 /keranjang
88 2026-03-14 09:18:03 /checkout
88 2026-03-14 20:41:15 /produk/minyak-goreng
88 2026-03-14 20:43:50 /keranjang
Setelah sessionization dengan ambang 30 menit, user 88 punya 2 sesi: satu pagi (3 event, durasi 4 menit) dan satu malam (2 event, durasi 2,5 menit).
Query ringkasan per sesi:
SELECT user_id,
nomor_sesi,
MIN(waktu) AS mulai,
MAX(waktu) - MIN(waktu) AS durasi,
COUNT(*) AS jumlah_event
FROM sesi
GROUP BY user_id, nomor_sesi;
Angka agregatnya menarik:
| Metrik | Nilai |
|---|---|
| Total sesi | 9.640 |
| Sesi per user | 2,31 |
| Event per sesi | 6,47 |
| Median durasi sesi | 3 menit 12 detik |
| Sesi berisi 1 event doang | 28% |
Yang bikin aku berhenti: 28 persen sesi cuma berisi satu event. Orang buka satu halaman, terus pergi.
Kalau kamu masukin sesi-sesi ini ke rata-rata durasi, angkanya keseret ke bawah — rata-rata jatuh ke 2 menit 4 detik, padahal sesi yang beneran aktif punya median 5 menit 40 detik.
Kesimpulannya beda total tergantung kamu keluarin sesi satu-event atau nggak. Ini keputusan yang harus kamu ambil sadar-sadar, bukan kebetulan.
Kesalahan umum saat sessionization
- Lupa PARTITION BY user_id. Tanpa itu, event dari user berbeda bakal nyambung jadi satu sesi. Angkanya bakal ngaco dan nggak keliatan salah.
- Pakai RANGE, bukan ROWS, di SUM kumulatif. Kalau ada dua event dengan timestamp identik,
RANGEbakal ngasih hasil yang beda dari yang kamu harapin. - Bandingin timestamp yang beda timezone. Log dari server bisa UTC, log dari app bisa WIB. Selisih 7 jam bikin tiap event jadi sesi baru.
- Ngasumsikan sesi satu-event itu bug. Bukan. Itu perilaku nyata, dan biasanya sinyal halaman landing yang jelek.
- Ambang batas 30 menit tanpa dicek. Cek dulu distribusi jeda di data kamu sendiri.
Sintaks window function ini standar SQL, tapi tiap database punya aturan interval yang beda. Cek dokumentasi resmi PostgreSQL soal window function kalau kamu pakai Postgres.
FAQ
Apa itu sessionization di SQL?
Sessionization adalah proses ngelompokkan event berurutan dari satu user jadi kelompok yang disebut sesi. Aturannya berbasis jeda waktu: kalau jarak antara satu event dengan event sebelumnya lewat ambang batas tertentu, event itu dianggap awal sesi baru. Di SQL, ini dikerjain pakai LAG buat lihat event sebelumnya, terus SUM kumulatif buat ngasih nomor sesi.
Kenapa ambang batasnya 30 menit?
Angka 30 menit itu warisan dari Google Analytics dan udah jadi standar de facto, bukan hukum alam. Buat aplikasi yang dipakai cepat kayak ojek online, 15 menit lebih masuk akal. Cara nentuinnya: lihat distribusi jeda antar event, cari titik di mana jumlah jeda mulai anjlok.
Bisa sessionization tanpa window function?
Bisa tapi jauh lebih ribet dan lambat, biasanya pakai self-join yang bandingin tiap baris dengan baris sebelumnya. Semua database modern yang umum dipakai — PostgreSQL, MySQL 8, BigQuery, SQL Server — udah dukung LAG dan SUM OVER.
Gimana ngitung durasi sesi?
Setelah tiap event punya session_id, kelompokkan per session_id lalu kurangin timestamp terakhir dengan timestamp pertama. Sesi yang cuma berisi satu event bakal keluar nol, dan itu bukan bug. Banyak tim yang milih ngeluarin sesi satu-event dari rata-rata durasi supaya angkanya nggak keseret ke bawah.
Apa bedanya sesi dan user?
Satu user bisa punya banyak sesi. Buka aplikasi pagi, siang, dan malam = satu user tiga sesi. Makanya metrik kayak conversion rate harus jelas pembaginya: per sesi atau per user. Dua angka itu bisa beda jauh.
Penutup
Rangkumannya:
- LAG buat lihat event sebelumnya, CASE buat nandain sesi baru, SUM kumulatif buat kasih nomor sesi.
- Ambang 30 menit itu titik awal, bukan jawaban. Cek data kamu.
- Putuskan sadar-sadar mau masukin sesi satu-event ke rata-rata atau nggak.
Kalau window function masih terasa asing, mulai dari fungsi LAG dan definisi window function di glossary. Dua itu pondasi buat semua query pola-waktu.
Habis ini, coba pakai hasil sesinya buat bikin chart tren harian — aturannya ada di kapan pakai line chart.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel Terkait
7 SQL Client Gratis Terbaik buat Analis Data (2026)
Nggak perlu bayar buat nulis query. Ini 7 SQL client gratis yang beneran dipakai analis, plus kelebihan dan kekurangannya masing-masing.
SQL Style Guide: Cara Nulis Query yang Enak Dibaca Tim
Sepuluh aturan SQL style guide yang bikin query kamu kebaca sama tim — dan sama kamu sendiri 6 bulan lagi. Lengkap dengan contoh sebelum-sesudah.
Take-Home Test SQL Data Analyst: Contoh Soal + Cara Ngerjainnya
Contoh soal take-home test SQL yang beneran dipakai perusahaan, dikerjain step by step — dari baca soal, nulis query, sampai nyusun insight yang bikin recruiter nengok.