Take-Home Test SQL Data Analyst: Contoh Soal + Cara Ngerjainnya
TL;DR
Take-home test SQL data analyst adalah tes rekrutmen di mana kamu dikasih dataset dan 3–5 pertanyaan bisnis untuk dijawab pakai query, biasanya dengan tenggat 24–72 jam. Yang dinilai bukan cuma query jalan, tapi juga kerapian kode, kejelasan asumsi, dan insight bisnis yang kamu tarik. Nilai paling gampang naik dari hal sepele: kasih README, tulis asumsi, dan jawab pertanyaan bisnisnya — bukan cuma tempel angka.
Take-home test SQL data analyst adalah tes rekrutmen di mana kamu dikasih dataset mentah dan 3–5 pertanyaan bisnis, lalu diminta jawab pakai query dalam 24–72 jam.
Yang bikin kandidat gugur di tahap ini jarang soal sintaks. Query-nya jalan, angkanya keluar, tapi jawabannya berhenti di angka. Nggak ada rekomendasi. Nggak ada asumsi yang ditulis.
Aku bikin ulang satu soal take-home yang polanya paling sering muncul, terus kerjain dari awal sampai kirim. Datasetnya toko_berkah — data transaksi UMKM retail.
Take-home test SQL itu ngetes apa sih?
Tiga hal, dan cuma satu yang soal SQL.
Pertama, apakah kamu bisa nerjemahin pertanyaan bisnis jadi query. Kedua, apakah kamu ngecek data sebelum ngitung. Ketiga, apakah kamu bisa balikin angka jadi rekomendasi yang bisa dieksekusi.
Reviewer biasanya baca jawaban kamu 10–15 menit. Kalau dalam 2 menit pertama mereka belum nemu kesimpulan, nilai kamu udah turun duluan.
Contoh soalnya kayak gimana?
Ini pola soal yang paling sering aku lihat, dengan 4 tabel: transaksi, transaksi_detail, produk, pelanggan.
Konteks: Toko Berkah jual produk grocery di 6 kota. Manajemen mau tau kesehatan bisnis sepanjang 2026.
- Gimana tren revenue bulanan? Ada bulan yang anjlok?
- Kategori produk apa yang paling laku di tiap kota?
- Dari pelanggan yang pertama belanja di Januari, berapa persen yang balik dalam 90 hari?
- Berdasarkan temuan di atas, satu rekomendasi apa yang kamu kasih ke tim?
Deliverable: file .sql + ringkasan 1 halaman. Waktu: 48 jam.
Pertanyaan nomor 4 itu yang paling banyak nilainya. Dan paling sering dianggap remeh.
Langkah 0: cek datanya dulu, jangan langsung ngitung
Sebelum nulis query jawaban, aku selalu jalanin ini dulu:
SELECT
COUNT(*) AS total_baris,
COUNT(DISTINCT id) AS id_unik,
SUM(CASE WHEN total_belanja IS NULL THEN 1 ELSE 0 END) AS belanja_null,
SUM(CASE WHEN total_belanja <= 0 THEN 1 ELSE 0 END) AS belanja_nol_minus,
MIN(tanggal_transaksi) AS tanggal_awal,
MAX(tanggal_transaksi) AS tanggal_akhir
FROM transaksi;
Di dataset ini hasilnya: 18.420 baris, 18.420 id unik, 0 NULL, tapi ada 214 transaksi dengan nilai negatif — itu retur yang belum dipisah.
Kalau kamu langsung SUM tanpa ngecek, revenue kamu kekurangan Rp 31,2 juta dan kamu nggak akan sadar.
Ini yang aku tulis di README: retur dikeluarin dari perhitungan revenue kotor, tapi dicatat terpisah. Reviewer suka ini.
Soal 1: gimana tren revenue bulanan?
Pakai CTE biar kebaca, terus LAG buat bandingin sama bulan sebelumnya.
WITH revenue_bulanan AS (
SELECT
DATE_TRUNC('month', tanggal_transaksi) AS bulan,
SUM(total_belanja) AS revenue
FROM transaksi
WHERE status = 'selesai'
AND total_belanja > 0
GROUP BY 1
)
SELECT
bulan,
revenue,
ROUND(
100.0 * (revenue - LAG(revenue) OVER (ORDER BY bulan))
/ NULLIF(LAG(revenue) OVER (ORDER BY bulan), 0),
1
) AS growth_mom_persen
FROM revenue_bulanan
ORDER BY bulan;
NULLIF di penyebut itu penting. Tanpa itu, bulan pertama bakal bikin query error kalau revenue-nya kebetulan 0.
Hasilnya:
| Bulan | Revenue | Growth MoM |
|---|---|---|
| Jan 2026 | Rp 412 jt | — |
| Feb 2026 | Rp 388 jt | -5,8% |
| Mar 2026 | Rp 501 jt | +29,1% |
| Apr 2026 | Rp 337 jt | -32,7% |
| Mei 2026 | Rp 356 jt | +5,6% |
April anjlok 32,7%. Kandidat biasa berhenti di sini dan nulis "April turun".
Kandidat yang lolos nanya kenapa. Maret ada Ramadan — belanja grocery naik. April Lebaran lewat, dan permintaannya balik normal. Turunnya bukan masalah, itu efek musiman.
Buktinya: April 2026 (Rp 337 jt) masih di atas rata-rata bulan non-Ramadan (Rp 318 jt). Angka ini yang bikin kesimpulan kamu punya bobot.
Soal 2: kategori apa yang paling laku per kota?
Ini soal ranking dalam grup. Polanya selalu sama: agregat dulu, terus ROW_NUMBER.
WITH penjualan_kategori AS (
SELECT
p.kota,
pr.kategori,
SUM(td.qty * td.harga_satuan) AS revenue
FROM transaksi t
JOIN transaksi_detail td ON td.transaksi_id = t.id
JOIN produk pr ON pr.id = td.produk_id
JOIN pelanggan p ON p.id = t.pelanggan_id
WHERE t.status = 'selesai'
GROUP BY p.kota, pr.kategori
)
SELECT kota, kategori, revenue, peringkat
FROM (
SELECT
kota,
kategori,
revenue,
ROW_NUMBER() OVER (PARTITION BY kota ORDER BY revenue DESC) AS peringkat
FROM penjualan_kategori
) x
WHERE peringkat <= 5
ORDER BY kota, peringkat;
Kenapa ROW_NUMBER dan bukan RANK? Karena kalau ada dua kategori dengan revenue sama persis, RANK bakal ngasih dua peringkat 1 dan kamu dapat 6 baris per kota. Tulis alasan ini di README — nunjukin kamu paham bedanya. ROW_NUMBER selalu ngasih nomor unik.
Temuan yang menarik dari dataset ini: kategori Minuman juara di 5 dari 6 kota. Tapi di Surabaya, juaranya Bumbu Dapur — dengan revenue 41% lebih tinggi dari Minuman di kota yang sama.
Satu anomali kayak gini lebih berharga dari 10 baris tabel yang seragam.
Soal 3: berapa persen pelanggan Januari yang balik lagi?
Ini soal cohort. Polanya: cari tanggal transaksi pertama, filter cohort, cek transaksi berikutnya dalam window waktu.
WITH pembelian_pertama AS (
SELECT
pelanggan_id,
MIN(tanggal_transaksi) AS tanggal_pertama
FROM transaksi
WHERE status = 'selesai'
GROUP BY pelanggan_id
),
cohort_januari AS (
SELECT pelanggan_id, tanggal_pertama
FROM pembelian_pertama
WHERE tanggal_pertama >= '2026-01-01'
AND tanggal_pertama < '2026-02-01'
),
balik_lagi AS (
SELECT DISTINCT c.pelanggan_id
FROM cohort_januari c
JOIN transaksi t
ON t.pelanggan_id = c.pelanggan_id
AND t.tanggal_transaksi > c.tanggal_pertama
AND t.tanggal_transaksi <= c.tanggal_pertama + INTERVAL '90 days'
WHERE t.status = 'selesai'
)
SELECT
COUNT(DISTINCT c.pelanggan_id) AS total_cohort,
COUNT(DISTINCT b.pelanggan_id) AS balik_belanja,
ROUND(
100.0 * COUNT(DISTINCT b.pelanggan_id)
/ NULLIF(COUNT(DISTINCT c.pelanggan_id), 0),
1
) AS retensi_90_hari_persen
FROM cohort_januari c
LEFT JOIN balik_lagi b ON b.pelanggan_id = c.pelanggan_id;
Perhatiin t.tanggal_transaksi > c.tanggal_pertama. Tanpa tanda lebih besar itu, transaksi pertama ikut kehitung dan retensi kamu jadi 100%. Ini bug yang paling sering muncul di jawaban kandidat.
Hasil di dataset ini: dari 1.284 pelanggan cohort Januari, cuma 287 yang balik dalam 90 hari. Retensi 22,4%.
Soal 4: rekomendasinya apa?
Di sinilah kandidat menang atau kalah.
Jawaban yang lemah: "Tingkatkan retensi pelanggan." Nggak ada yang bisa dikerjain dari kalimat itu.
Jawaban yang kuat nyambungin dua temuan jadi satu aksi:
Retensi 90 hari cuma 22,4%, artinya 997 dari 1.284 pelanggan baru Januari nggak pernah balik. Di sisi lain, Bumbu Dapur di Surabaya punya revenue 41% di atas kategori lain — sinyal produk yang dibeli berulang.
Rekomendasi: kirim voucher Bumbu Dapur ke pelanggan Surabaya di hari ke-30 setelah transaksi pertama. Kalau retensi naik 5 poin ke 27%, itu tambahan ~64 pelanggan aktif dari cohort Januari doang.
Yang perlu dicek dulu: apakah 41% itu bertahan setelah dikontrol jumlah outlet per kota.
Tiga hal ada di situ: angka, aksi konkret, dan pengakuan atas keterbatasan.
Kesalahan umum yang bikin gugur
Ngirim file .sql doang. Reviewer nggak mau jalanin query kamu. Kasih hasilnya dalam tabel, sekalian ringkasan.
SELECT * di query final. Kelihatan kayak kamu nggak tau kolom mana yang kamu butuh.
Nggak nulis asumsi. 214 transaksi negatif itu ada di data. Kalau kamu diem aja, reviewer nggak tau kamu ngeliatnya atau nggak.
Bikin 12 query buat 3 pertanyaan. Fokus. Query yang nggak dipakai buat jawab pertanyaan, buang.
Nggak nge-format. Indentasi berantakan bikin reviewer capek. Standar penulisan query yang enak dibaca bisa kamu contek dari SQL Style Guide-nya Simon Holywell.
Checklist sebelum kirim
- Semua query jalan dari nol di database kosong (nggak ada dependensi ke tabel temporary yang lupa kamu buat).
- Ada README: asumsi, baris yang dibuang, dan alasannya.
- Tiap pertanyaan punya jawaban satu kalimat di paling atas, angka pendukung di bawahnya.
- Ada minimal satu rekomendasi yang bisa dikerjain minggu depan.
- Nama kolom hasil pakai bahasa manusia, bukan
col1.
FAQ
Berapa lama waktu ngerjain take-home test SQL?
Kebanyakan perusahaan kasih 24–72 jam, tapi tesnya sendiri dirancang buat 2–4 jam kerja. Jangan pakai semua waktu yang dikasih. Kalau kamu kirim setelah 70 jam untuk soal 3 pertanyaan, itu sinyal kamu kesulitan. Target aku biasanya: kerjain dalam satu sesi 3 jam, endapin semalam, review pagi, kirim.
Boleh pakai AI buat ngerjain take-home test SQL?
Tergantung aturan perusahaan — baca instruksinya dulu. Kalau boleh, pakai AI buat cek sintaks atau nyari fungsi yang lupa, bukan buat nulis seluruh jawaban. Masalahnya, tahap berikutnya biasanya technical interview yang bahas query kamu baris per baris. Kalau kamu nggak paham query sendiri, ketahuan dalam 5 menit.
Lebih penting query yang efisien atau insight yang bagus?
Insight, di hampir semua kasus. Take-home test data analyst nguji apakah kamu bisa nerjemahin pertanyaan bisnis jadi angka, lalu balik lagi jadi rekomendasi. Query yang jalan tapi kesimpulannya kosong nilainya rendah. Query yang agak lambat tapi jawabannya tajam biasanya lolos. Optimasi baru jadi kriteria utama di level data engineer.
Gimana kalau datanya kotor dan ada nilai aneh?
Itu sengaja. Hampir semua take-home test nyelipin duplikat, NULL, atau transaksi bernilai negatif buat lihat apakah kamu ngecek data sebelum ngitung. Jangan diem-diem hapus. Tulis di README: berapa baris yang kamu buang, kenapa, dan apa efeknya ke hasil. Ini sering jadi pembeda antara kandidat yang lolos dan yang nggak.
Perlu bikin visualisasi juga?
Kalau nggak diminta, satu atau dua chart sederhana cukup dan bikin nilai naik. Jangan bikin dashboard 8 panel. Satu line chart tren dan satu bar chart perbandingan segmen udah lebih dari cukup buat nunjukin kamu bisa milih visual yang pas sama pertanyaannya.
Penutup
Take-home test SQL menang di tiga tempat: cek data sebelum ngitung, tulis asumsi, dan tutup dengan rekomendasi yang punya angka.
Query-nya sendiri cuma butuh CTE, JOIN, dan window function. Nggak ada yang eksotis.
Kalau window function masih bikin pusing, mampir ke panduan window function SQL. Buat latihan pola cohort dan retensi, ada dataset UMKM yang bisa kamu utak-atik di tutorial cohort analysis.
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.
Latihan Soal SQL Menengah: Window Function & CTE
8 soal SQL level menengah pakai window function dan CTE, lengkap dengan jawaban, penjelasan, dan jebakan yang sering bikin orang salah.