Cara Membuat Pivot Dinamis di SQL (Panduan 2026)
TL;DR
Pivot di SQL ngubah nilai baris jadi kolom pakai SUM dengan CASE WHEN, satu CASE per kolom target. Disebut dinamis kalau daftar kolomnya nggak diketik manual tapi dibangun otomatis dari data, biasanya lewat query yang ngerakit teks SQL pakai string_agg lalu dijalanin. Cocok buat laporan yang jumlah kategorinya berubah-ubah.
Pivot dinamis di SQL ngubah nilai baris jadi kolom tanpa kamu ngetik satu per satu nama kolomnya. Kolomnya ngikut data secara otomatis.
Kasus klasiknya: kamu punya data penjualan per produk per bulan dalam bentuk baris panjang, tapi bos minta tabel dengan produk di baris dan bulan jadi kolom.
Di sini kamu bakal belajar cara bikin pivot manual pakai CASE WHEN dulu, terus naik ke versi dinamis yang kolomnya kebentuk sendiri dari data.
Apa itu pivot di SQL?
Pivot di SQL adalah teknik ngubah nilai dari satu kolom jadi beberapa kolom baru, sambil ngagregasi angkanya. Data yang tadinya memanjang ke bawah (satu baris per bulan) jadi melebar ke samping (satu kolom per bulan). SQL standar nggak punya perintah PIVOT bawaan, jadi caranya pakai CASE WHEN di dalam fungsi agregasi.
Pivot disebut dinamis kalau daftar kolomnya nggak diketik manual, tapi dibangun otomatis dari isi data. Jadi kalau ada kategori baru muncul, kolomnya nambah sendiri.
Gimana cara bikin pivot statis dengan CASE WHEN?
Sebelum ke dinamis, pahamin dulu versi manualnya. Idenya: tiap kolom target dibikin dari satu SUM yang cuma ngitung baris di bulan tertentu, sisanya dianggap nol.
SELECT
produk,
SUM(CASE WHEN EXTRACT(MONTH FROM tanggal) = 1 THEN nominal ELSE 0 END) AS jan,
SUM(CASE WHEN EXTRACT(MONTH FROM tanggal) = 2 THEN nominal ELSE 0 END) AS feb,
SUM(CASE WHEN EXTRACT(MONTH FROM tanggal) = 3 THEN nominal ELSE 0 END) AS mar
FROM penjualan
GROUP BY produk
ORDER BY produk;
Tiap CASE WHEN ngecek bulannya. Kalau cocok, nilai nominal ikut dijumlah. Kalau nggak, dia nyumbang nol. Hasilnya tabel dengan produk di kiri dan kolom jan, feb, mar di kanan.
Kelemahannya jelas: kalau kamu butuh 12 bulan, kamu ngetik 12 baris CASE WHEN. Kalau kategorinya ratusan, ini nggak masuk akal.
Gimana cara bikin pivot jadi dinamis?
Di sini triknya. SQL biasa nggak bisa bikin kolom dari hasil query dalam satu langkah, jadi prosesnya dua tahap. Pertama, rakit teks CASE WHEN-nya otomatis. Kedua, jalanin teks itu sebagai query.
Langkah pertama pakai string_agg buat nyambung potongan CASE WHEN buat tiap kategori unik.
SELECT string_agg(DISTINCT
format('SUM(CASE WHEN kategori = %L THEN nominal ELSE 0 END) AS %I',
kategori, kategori),
', ')
FROM penjualan;
Fungsi format ngisi %L dengan nilai kategori sebagai teks aman, dan %I sebagai nama kolom aman. Hasil query ini adalah satu string panjang berisi semua kolom CASE WHEN yang kamu butuh.
Langkah kedua, tempel string itu ke dalam query pivot lengkap. Di aplikasi nyata, kamu ambil hasilnya lewat kode (Python, misalnya) lalu susun query akhirnya.
SELECT produk, [hasil_string_agg_ditempel_di_sini]
FROM penjualan
GROUP BY produk;
Kalau kamu pengin semua dalam satu prosedur di PostgreSQL, kamu bisa bungkus pakai EXECUTE di dalam fungsi PL/pgSQL. Tapi buat mulai, dua tahap manual ini paling gampang dipahami.
Contoh kasus: rekap penjualan toko_berkah
Anggap toko_berkah, UMKM sembako di Bandung, punya tabel penjualan dengan kolom produk, kategori, tanggal, dan nominal. Ada 7 kategori dan pemiliknya mau rekap nominal per kategori dengan kategori jadi kolom.
Karena jumlah kategori bisa nambah tiap kali toko masukin lini baru, versi dinamis pas banget. Dari sampel data ngulikdata, pivot dinamis ini ngasilin tabel 7 kolom, dan yang menarik kategori 'sembako pokok' isinya Rp 71.500.000, hampir dua kali lipat kategori kedua terbesar yaitu 'minuman' di Rp 38.900.000.
Selisih setajam itu langsung kelihatan begitu data dilebarin jadi kolom. Kalau masih bentuk baris panjang, pola kayak gini lebih susah ditangkap sekilas.
Kesalahan umum saat bikin pivot dinamis
Nggak mengamankan input kolom. Kalau kamu rakit query dari nilai data mentah tanpa format aman, kamu kebuka ke SQL injection. Pakai %L dan %I lewat fungsi format, jangan sambung string asal.
Lupa GROUP BY. Pivot itu agregasi. Tanpa GROUP BY produk, SUM-nya ngga kepisah per baris dan hasilnya campur aduk.
Maksa dinamis padahal kategorinya tetap. Kalau kategori kamu cuma 12 bulan yang nggak berubah, pivot statis lebih simpel dan gampang dibaca. Dinamis baru worth it kalau kategorinya beneran berubah-ubah. Buat dasar teknik ini, pahamin dulu conditional aggregation dengan CASE. Sintaks lengkap fungsi string ada di dokumentasi PostgreSQL.
FAQ
Pertanyaan yang sering muncul soal pivot dinamis di SQL.
Apa bedanya pivot statis dan pivot dinamis di SQL?
Pivot statis itu kamu ketik sendiri tiap kolomnya pakai CASE WHEN, misalnya kolom Januari sampai Desember. Cocok kalau kategorinya tetap. Pivot dinamis bikin daftar kolomnya otomatis dari data, jadi kalau muncul kategori baru, kolomnya ikut nambah tanpa kamu edit query. Dinamis lebih ribet disiapin, tapi hemat waktu buat data yang berubah-ubah.
Kenapa SQL standar nggak punya perintah PIVOT?
SQL standar emang nggak punya kata kunci PIVOT bawaan, walau beberapa database kayak SQL Server dan Oracle punya sintaks sendiri. Di PostgreSQL dan MySQL, cara resminya pakai CASE WHEN di dalam agregasi. Pendekatan CASE WHEN ini justru paling portabel karena jalan di hampir semua database tanpa fitur khusus.
Gimana cara bikin kolom pivot muncul otomatis dari data?
Kamu perlu dua langkah. Pertama, jalanin query yang ngerakit potongan teks CASE WHEN buat tiap kategori pakai string_agg. Kedua, ambil teks hasilnya dan tempel ke dalam query pivot yang beneran, lalu jalanin. Karena SQL biasa nggak bisa bikin kolom dari hasil query dalam satu langkah, prosesnya emang dua tahap.
Kapan sebaiknya pivot dilakukan di SQL, bukan di Excel atau pandas?
Pivot di SQL masuk akal kalau datanya gede dan kamu mau ngurangin volume sebelum ditarik ke tools lain. Kalau datanya udah kecil dan kamu butuh interaktif, pivot table Excel atau pandas lebih fleksibel. Aturan praktisnya, biar SQL yang ngerjain agregasi berat, sisanya diserahin ke tools visual.
Apakah crosstab di PostgreSQL lebih baik dari CASE WHEN?
Fungsi crosstab dari ekstensi tablefunc bisa bikin pivot lebih ringkas, tapi butuh ekstensi dipasang dan sintaksnya lebih kaku soal tipe kolom. CASE WHEN lebih verbose tapi transparan dan jalan di mana aja. Buat mulai belajar, CASE WHEN lebih gampang dipahami karena kamu lihat jelas tiap kolom dibentuk dari mana.
Penutup
Pivot di SQL bertumpu pada satu ide: SUM dengan CASE WHEN buat tiap kolom target. Versi dinamis tinggal ngerakit CASE WHEN itu otomatis pakai string_agg, lalu jalanin hasilnya sebagai query kedua.
Mau ringkasan multi level tanpa muter baris? Cek GROUPING SETS di SQL. Buat fondasi CASE WHEN-nya, baca conditional aggregation.
Pengin lancar nulis query rekap yang beneran dipakai di kerjaan analis? Latihan langsung di NgulikSQL, lengkap sama dataset toko biar kamu terbiasa sama kasus nyata.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel terkait
CTE vs Subquery vs Temp Table: Mana Lebih Cepat
CTE, subquery, dan temp table sama-sama bikin hasil sementara, tapi performanya beda. Ini panduan milih yang mana buat query kamu.
Partisi Tabel di SQL untuk Data Besar
Partisi tabel memecah satu tabel besar jadi potongan kecil biar query cuma baca bagian yang relevan. Ini cara bikin dan kapan kamu butuh.
Covering Index di SQL untuk Query Lebih Cepat (2026)
Covering index bikin query cepat karena semua kolom yang dibutuhin ada di index, jadi database nggak perlu buka tabel utama.