UNPIVOT SQL: Ubah Kolom Jadi Baris biar Gampang Dianalisa
Blog/Tutorial SQL/UNPIVOT SQL: Ubah Kolom Jadi Baris biar Gampang Dianalisa

UNPIVOT SQL: Ubah Kolom Jadi Baris biar Gampang Dianalisa

BimaBima
·2 Mei 2026·10 menit baca

Penulis

Bima

Bima

Founder & Data Professional

Bagikan

TL;DR

UNPIVOT di SQL adalah operasi yang ngubah beberapa kolom jadi baris, ngerubah tabel dari format wide ke format long. Gunanya biar data gampang difilter, diagregasi, dan divisualisasi. Ada tiga cara: klausa UNPIVOT (SQL Server/Oracle), UNION ALL (jalan di semua database), dan CROSS JOIN LATERAL VALUES (paling ringkas di PostgreSQL). Di tabel laporan toko_berkah dengan 12 kolom bulan, UNPIVOT mangkas query agregasi dari 47 baris jadi 6 baris.

UNPIVOT di SQL adalah operasi yang ngubah beberapa kolom jadi baris. Tabel yang tadinya lebar — satu kolom per bulan — jadi panjang, dengan kolom bulan dan kolom penjualan.

Kenapa perlu? Coba kamu bikin query "total penjualan Q2" di tabel yang kolomnya jan, feb, mar sampai des.

SELECT produk, apr + mei + jun AS total_q2
FROM laporan_bulanan;

Jalan sih. Sampai bos minta "eh, sekalian bandingin sama Q2 tahun lalu, terus filter cuma bulan yang penjualannya di atas 10 juta."

Sekarang query kamu jadi neraka.

Di dataset toko_berkah, tabel laporannya punya 12 kolom bulan. Setelah aku UNPIVOT, query agregasi yang tadinya 47 baris jadi 6 baris.

Apa itu format wide dan format long?

Format wide nyimpen satu kategori per kolom. Enak dibaca manusia, susah diolah mesin.

produkjanfebmar
Beras Premium12.400.00011.800.00014.200.000
Minyak Goreng8.100.0009.300.0007.900.000

Format long nyimpen satu observasi per baris. Susah dibaca manusia, gampang banget diolah mesin.

produkbulanpenjualan
Beras Premiumjan12.400.000
Beras Premiumfeb11.800.000
Beras Premiummar14.200.000
Minyak Gorengjan8.100.000

Di format long, kamu bisa WHERE bulan = 'mar'. Di format wide, kamu nggak bisa — karena "mar" itu nama kolom, bukan nilai.

Itu bedanya. Dan itu yang bikin UNPIVOT penting.

Gimana cara UNPIVOT pakai klausa UNPIVOT?

Kalau kamu pakai SQL Server atau Oracle, ada klausa bawaan. Ini cara paling bersih.

SELECT produk, bulan, penjualan
FROM laporan_bulanan
UNPIVOT (
  penjualan FOR bulan IN (jan, feb, mar, apr, mei, jun,
                         jul, agu, sep, okt, nov, des)
) AS unpvt;

Cara bacanya:

  • penjualan = nama kolom baru buat nilainya
  • bulan = nama kolom baru buat nama kolom lamanya
  • IN (...) = daftar kolom yang mau diubah jadi baris

Dua syarat yang sering bikin error:

  1. Semua kolom di IN (...) harus punya tipe data yang sama. Kalau jan itu INT dan feb itu DECIMAL, cast dulu.
  2. Baris yang nilainya NULL otomatis dibuang. Kalau kamu butuh baris NULL tetap ada, pakai cara UNION ALL di bawah.

Gimana kalau database aku nggak punya UNPIVOT?

PostgreSQL, MySQL, dan SQLite nggak punya klausa UNPIVOT. Pakai UNION ALL — ini jalan di semua database tanpa kecuali.

SELECT produk, 'jan' AS bulan, jan AS penjualan FROM laporan_bulanan
UNION ALL
SELECT produk, 'feb', feb FROM laporan_bulanan
UNION ALL
SELECT produk, 'mar', mar FROM laporan_bulanan
UNION ALL
SELECT produk, 'apr', apr FROM laporan_bulanan;

Polanya sama tiap blok: nama kolom jadi teks literal, isi kolomnya jadi nilai.

Verbose? Iya, 12 bulan berarti 12 blok. Tapi jalan di mana aja.

Kalau kamu belum familiar sama cara kerja UNION, cek dulu fungsi UNION dan UNION ALL.

Satu kelemahan penting: UNION ALL scan tabelnya sekali per blok. 12 blok = 12 kali full table scan. Di tabel besar, ini kerasa banget.

Cara paling ringkas di PostgreSQL

PostgreSQL punya trik yang jauh lebih pendek dan cuma scan tabel sekali: CROSS JOIN LATERAL (VALUES ...).

SELECT l.produk, v.bulan, v.penjualan
FROM laporan_bulanan l
CROSS JOIN LATERAL (VALUES
  ('jan', l.jan),
  ('feb', l.feb),
  ('mar', l.mar),
  ('apr', l.apr),
  ('mei', l.mei),
  ('jun', l.jun)
) AS v(bulan, penjualan)
WHERE v.penjualan IS NOT NULL;

Cara kerjanya: buat tiap baris di laporan_bulanan, PostgreSQL bikin 6 baris kecil dari daftar VALUES itu, terus ditempel.

Klausa WHERE v.penjualan IS NOT NULL di akhir bikin perilakunya sama kayak klausa UNPIVOT bawaan — baris kosong dibuang.

MySQL 8 juga bisa pakai pola yang mirip lewat JOIN ke subquery VALUES, walaupun sintaksnya sedikit beda.

Contoh kasus: laporan bulanan toko_berkah

Kondisi awal: tabel laporan_bulanan dengan 240 baris produk dan 12 kolom bulan. Total 2.880 sel angka yang "kepenjara" di dalam header kolom.

Permintaan dari owner: "Kasih tau bulan mana yang penjualannya di bawah rata-rata, per produk. Terus urutkan dari yang paling parah."

Di format wide, ini butuh 12 perbandingan manual per produk. Aku nyoba, sampai 47 baris query dan masih belum bener.

Di format long, jadi gini:

WITH long_data AS (
  SELECT l.produk, v.bulan, v.penjualan
  FROM laporan_bulanan l
  CROSS JOIN LATERAL (VALUES
    ('jan', l.jan), ('feb', l.feb), ('mar', l.mar),
    ('apr', l.apr), ('mei', l.mei), ('jun', l.jun),
    ('jul', l.jul), ('agu', l.agu), ('sep', l.sep),
    ('okt', l.okt), ('nov', l.nov), ('des', l.des)
  ) AS v(bulan, penjualan)
  WHERE v.penjualan IS NOT NULL
),
rata_rata AS (
  SELECT produk, AVG(penjualan) AS avg_produk
  FROM long_data
  GROUP BY produk
)
SELECT
  d.produk,
  d.bulan,
  d.penjualan,
  ROUND(r.avg_produk, 0) AS rata_rata_produk,
  ROUND((d.penjualan - r.avg_produk) / r.avg_produk * 100, 1) AS selisih_persen
FROM long_data d
JOIN rata_rata r ON d.produk = r.produk
WHERE d.penjualan < r.avg_produk
ORDER BY selisih_persen ASC
LIMIT 20;

Hasilnya nunjukin pola yang nggak kelihatan di format wide: Minyak Goreng anjlok 38% di bawah rata-ratanya sendiri di bulan Juli. Bukan cuma satu produk — 6 dari 10 produk kebutuhan pokok kena penurunan besar di Juli.

Setelah dicek, Juli 2025 itu minggu setelah Lebaran. Stok belum masuk lagi.

Insight yang muncul cuma gara-gara datanya dibalik bentuknya.

Buat mainin agregasi kayak gini, kamu bakal butuh GROUP BY dan AVG. Konsep CTE-nya ada di glossary CTE.

Kesalahan umum waktu UNPIVOT

Tipe data kolomnya beda-beda

Klausa UNPIVOT nolak kalau kolom yang mau digabung tipe datanya campur. Cast semuanya dulu:

SELECT produk,
       CAST(jan AS DECIMAL(15,2)) AS jan,
       CAST(feb AS DECIMAL(15,2)) AS feb
FROM laporan_bulanan

Lupa baris NULL kebuang

Kalau produk baru launching di bulan Agustus, sel jan sampai jul-nya NULL. Klausa UNPIVOT buang baris itu. Kadang itu yang kamu mau, kadang enggak — kalau kamu lagi ngitung berapa bulan produk itu nol penjualan, kamu butuh baris itu tetap ada.

Pakai UNION ALL di tabel jutaan baris

12 blok UNION ALL = 12 kali scan tabel. Di tabel 5 juta baris, query yang harusnya 2 detik bisa jadi 40 detik. Pindah ke CROSS JOIN LATERAL kalau bisa.

Nama bulan jadi teks, tapi urutannya berantakan

Kalau kamu ORDER BY bulan dan bulannya teks, urutannya jadi alfabetis: agu, apr, des, feb... Bikin kolom bantu berisi angka bulan:

CROSS JOIN LATERAL (VALUES
  (1, 'jan', l.jan),
  (2, 'feb', l.feb),
  (3, 'mar', l.mar)
) AS v(no_bulan, bulan, penjualan)

Terus ORDER BY no_bulan.

FAQ

Apa bedanya PIVOT dan UNPIVOT?

PIVOT ngubah baris jadi kolom — dari data panjang jadi tabel lebar yang enak dibaca manusia. UNPIVOT kebalikannya, ngubah kolom jadi baris biar data gampang diolah mesin. Patokannya: kalau kamu lagi nyiapin laporan buat dibaca orang, PIVOT. Kalau kamu lagi nyiapin data buat dianalisa atau divisualisasi, UNPIVOT dulu.

Database apa aja yang punya klausa UNPIVOT?

SQL Server dan Oracle punya klausa UNPIVOT bawaan. PostgreSQL, MySQL, dan SQLite nggak punya. Buat database yang nggak punya, pakai UNION ALL — ini jalan di semua database tanpa kecuali. Kalau kamu di PostgreSQL, ada cara yang lebih ringkas pakai CROSS JOIN LATERAL VALUES atau fungsi unnest().

UNPIVOT ngapain sama nilai NULL?

Klausa UNPIVOT bawaan otomatis buang baris yang nilainya NULL. Jadi kalau produk A nggak ada penjualan di bulan Maret dan selnya NULL, baris Maret buat produk A nggak muncul di hasil. Kalau kamu pakai UNION ALL, baris NULL-nya tetap ikut — tambahin WHERE ... IS NOT NULL kalau mau perilaku yang sama.

Kenapa data format long lebih enak buat analisa?

Soalnya tiap baris jadi satu observasi yang lengkap: produk, bulan, angka. Kamu bisa langsung GROUP BY bulan, filter WHERE bulan = 'mei', atau lempar ke chart tanpa nyusun ulang. Di format wide, nambah satu bulan baru artinya kamu harus edit semua query yang nyebut nama kolom bulan satu-satu.

UNPIVOT bikin query lambat nggak?

Buat tabel kecil sampai sedang, dampaknya kecil. Yang bikin lambat biasanya UNION ALL, soalnya dia scan tabel sekali per kolom — 12 kolom bulan berarti 12 kali full scan. Klausa UNPIVOT dan CROSS JOIN LATERAL cuma scan sekali, jadi lebih cepat. Kalau tabelnya jutaan baris dan sering dipakai, mending simpan hasilnya sebagai view atau tabel terpisah.

Penutup

Tiga hal yang perlu kamu inget:

  • Data yang kolomnya jan–des itu tanda kamu butuh UNPIVOT sebelum analisa.
  • SQL Server dan Oracle: pakai klausa UNPIVOT. Yang lain: UNION ALL atau CROSS JOIN LATERAL VALUES.
  • Hati-hati NULL — klausa UNPIVOT buang baris kosong, UNION ALL enggak.

Sintaks lengkap klausa UNPIVOT ada di dokumentasi resmi Microsoft T-SQL.

Kalau data kamu masih di Excel atau CSV dan belum masuk database, unpivot bisa dilakuin lebih cepet lewat Power Query. Caranya ada di panduan Power Query di Power BI.

Mau latihan nulis query UNPIVOT sendiri sampai lancar? Coba latihan interaktifnya di NgulikSQL.

Coba Langsung

Mau praktek langsung? Mulai latihan SQL gratis

Latihan interaktif, langsung di browser.

Buka NgulikSQL →
Bagikan:
Bima
Ditulis oleh

Bima

Founder & Data Professional

Founder Ngulik Data. Passionate about making data analysis accessible for everyone.

Artikel Terkait

7 SQL Client Gratis Terbaik buat Analis Data (2026)
Tutorial SQL
10 Juli 2026•9 menit baca

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.

BimaBima
SQL Style Guide: Cara Nulis Query yang Enak Dibaca Tim
Tutorial SQL
7 Juli 2026•9 menit baca

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.

BimaBima
Take-Home Test SQL Data Analyst: Contoh Soal + Cara Ngerjainnya
Tutorial SQL
4 Juli 2026•11 menit baca

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.

BimaBima
Kembali ke Blog
Ngulik Data logoNgulik Data

Platform edukasi data lengkap untuk professionals Indonesia. Belajar SQL, Data Analysis, dan lebih banyak lagi dengan praktek langsung dan feedback real-time.

Copyright © 2026 - All rights reserved

LINKS
SupportPricingDatasetBlogAffiliates
LEGAL
Terms of servicesPrivacy policy
Ngulik Data
DatasetLeaderboardBlogStore