Membuat Tabel Kalender (Date Dimension) di SQL
TL;DR
Tabel kalender atau date dimension adalah tabel permanen yang nyimpen satu baris per tanggal, lengkap dengan atribut kayak tahun, bulan, kuartal, nama hari, dan penanda akhir pekan. Tabel ini di-JOIN ke tabel fakta lewat kolom tanggal, biar laporan per periode nggak perlu ngitung ulang atribut waktu tiap query. Cara ngisinya paling gampang pakai generate_series di PostgreSQL, dipadukan dengan EXTRACT dan TO_CHAR buat tiap kolomnya.
Tabel kalender atau date dimension adalah tabel permanen yang nyimpen satu baris per tanggal, lengkap dengan atribut kayak tahun, bulan, kuartal, dan nama hari. Satu tabel buat bikin laporan per periode berhenti ngitung ulang tanggal tiap query.
Kalau kamu sering nulis EXTRACT dan CASE buat nentuin kuartal, hari kerja, atau musim di tiap laporan, kamu ngulang kerjaan yang sama terus. Definisi kuartal bahkan bisa beda antar analis kalau nggak diseragamkan.
Tabel kalender naruh semua atribut itu di satu tempat. Tulis logikanya sekali, lalu semua laporan tinggal JOIN.
Apa itu tabel kalender di SQL?
Tabel kalender adalah tabel yang punya satu baris untuk tiap tanggal dalam rentang tertentu, misalnya 2024 sampai 2027. Tiap baris nyimpan atribut siap pakai: tahun, bulan, nama bulan, kuartal, nama hari, minggu ke berapa, dan penanda akhir pekan. Di data warehouse, tabel ini disebut dimension table buat waktu.
Perannya sentral di star schema, model data yang paling umum di BI. Tabel fakta (transaksi) nyimpen angka, tabel dimensi nyimpen konteks. Tabel kalender adalah dimensi waktunya.
Kenapa perlu tabel kalender, bukan ngitung langsung?
Ngitung atribut tanggal di tiap query bikin tiga masalah. Kode berulang, query lebih lambat, dan definisi yang bisa beda antar orang. Tabel kalender ngeberesin ketiganya. Logika ditulis sekali, disimpan, dan dipakai bareng.
Ada juga keuntungan yang jarang kepikiran: analisa hari libur dan periode fiskal. Kamu bisa nambah kolom is_libur atau kuartal_fiskal yang nggak mungkin dihitung dari tanggal saja, karena butuh aturan khusus perusahaan.
Gimana struktur kolom tabel kalender?
Mulai dari kolom yang paling sering kepakai. Kamu bisa nambah sesuai kebutuhan.
| Kolom | Isi | Contoh |
|---|---|---|
| tanggal | Kunci utama, tanggal murni | 2026-08-25 |
| tahun | Tahun 4 digit | 2026 |
| bulan | Bulan angka | 8 |
| nama_bulan | Nama bulan teks | Agustus |
| kuartal | Kuartal 1 sampai 4 | 3 |
| nama_hari | Nama hari teks | Selasa |
| is_weekend | Penanda akhir pekan | false |
Gimana cara bikin dan isi tabel kalender di PostgreSQL?
Bikin tabelnya dulu, lalu isi pakai generate_series yang dipadukan sama EXTRACT dan TO_CHAR.
CREATE TABLE dim_tanggal (
tanggal DATE PRIMARY KEY,
tahun INT,
bulan INT,
nama_bulan TEXT,
kuartal INT,
hari INT,
nama_hari TEXT,
minggu_ke INT,
is_weekend BOOLEAN
);
INSERT INTO dim_tanggal
SELECT
d::date,
EXTRACT(YEAR FROM d),
EXTRACT(MONTH FROM d),
TO_CHAR(d, 'TMMonth'),
EXTRACT(QUARTER FROM d),
EXTRACT(DAY FROM d),
TO_CHAR(d, 'TMDay'),
EXTRACT(WEEK FROM d),
EXTRACT(ISODOW FROM d) IN (6, 7)
FROM generate_series('2024-01-01'::date, '2027-12-31'::date, '1 day') AS d;
Dua fungsi yang jadi kunci. EXTRACT ngambil angka kayak tahun dan kuartal. TO_CHAR ngasih teks kayak nama hari. Awalan TM di TO_CHAR bikin nama hari dan bulan ngikutin bahasa lokal server, bukan selalu Inggris. ISODOW ngasih 6 dan 7 buat Sabtu dan Minggu.
Sekali jalan, query ini ngisi 1.461 baris (4 tahun). Buat MySQL, ganti generate_series pakai recursive CTE buat deret tanggalnya dulu, lalu turunin atribut pakai YEAR(), MONTH(), dan DAYNAME().
Gimana cara pakai tabel kalender di laporan?
JOIN tabel fakta ke dim_tanggal lewat kolom tanggal, lalu GROUP BY atribut yang kamu mau. Karena atributnya udah jadi, query laporan jadi pendek.
SELECT
dt.tahun,
dt.kuartal,
SUM(t.total_harga) AS omzet
FROM transaksi t
JOIN dim_tanggal dt ON dt.tanggal = t.tanggal
GROUP BY dt.tahun, dt.kuartal
ORDER BY dt.tahun, dt.kuartal;
Nggak ada EXTRACT di query ini. Semua atribut diambil dari tabel kalender. Mau ganti ke laporan per nama hari? Tinggal ganti GROUP BY-nya ke dt.nama_hari.
Contoh kasus: analisa akhir pekan Toko Berkah
Toko Berkah, UMKM kelontong di dataset latihan ngulikdata, punya 6.240 transaksi selama setahun. Pemiliknya penasaran, akhir pekan itu beneran lebih ramai atau cuma perasaan.
Tanpa tabel kalender, tiap analis harus nulis logika penentuan akhir pekan sendiri, dan gampang keliru. Dengan kolom is_weekend yang udah jadi, jawabannya satu JOIN.
SELECT
dt.is_weekend,
COUNT(*) AS jml_transaksi,
SUM(t.total_harga) AS omzet
FROM transaksi t
JOIN dim_tanggal dt ON dt.tanggal = t.tanggal
GROUP BY dt.is_weekend;
Hasilnya kebuka. Akhir pekan cuma 2 dari 7 hari (29% waktu), tapi nyumbang 41% dari total omzet setahun. Rata-rata transaksi per hari akhir pekan Rp4.870.000, hampir dua kali lipat hari kerja yang Rp2.610.000.
Berdasarkan angka ini, pemilik toko nambah satu kasir tiap Sabtu-Minggu dan mindahin jadwal restock ke Jumat pagi, biar rak penuh sebelum lonjakan akhir pekan. Semua keputusan itu berangkat dari satu kolom di tabel kalender.
Kesalahan umum saat bikin tabel kalender
Rentang tanggal kependekan. Bikin tabel cuma buat tahun berjalan bikin kamu harus isi ulang tiap tahun. Isi sekaligus beberapa tahun ke depan, misalnya sampai 2030.
Lupa kunci utama di kolom tanggal. Tanpa PRIMARY KEY di tanggal, JOIN ke tabel fakta lambat dan bisa ada duplikat. Selalu jadikan tanggal kunci utama.
Nyimpen nama hari dalam bahasa Inggris padahal laporan Indonesia. Pakai awalan TM di TO_CHAR dan set locale server, atau isi manual pakai CASE kalau butuh kontrol penuh.
Nggak nambah kolom libur nasional. Akhir pekan bisa dihitung otomatis, tapi libur nasional butuh diisi manual. Tanpa ini, analisa hari kerja bakal keliru di sekitar tanggal merah. Buat referensi fungsi tanggal, cek dokumentasi date functions PostgreSQL.
FAQ
Apa itu tabel kalender atau date dimension di SQL?
Tabel kalender adalah tabel permanen yang punya satu baris untuk tiap tanggal dalam rentang tertentu, misalnya 2024 sampai 2030. Tiap baris nyimpan atribut siap pakai: tahun, bulan, nama bulan, kuartal, nama hari, minggu ke berapa, dan penanda akhir pekan atau libur. Di dunia data warehouse, tabel ini disebut date dimension dan jadi bagian inti dari star schema.
Kenapa perlu tabel kalender, bukan ngitung tanggal langsung?
Ngitung atribut tanggal langsung di tiap query bikin kode berulang dan lambat. Dengan tabel kalender, logika kayak penentuan kuartal atau hari libur ditulis sekali dan disimpan. Semua laporan tinggal JOIN ke tabel itu, jadi definisi kuartal atau minggu konsisten di seluruh tim. Ini juga bikin query lebih cepat karena atributnya udah jadi, bukan dihitung ulang tiap kali.
Gimana cara isi tabel kalender di PostgreSQL?
Pakai generate_series buat bikin deret tanggal, lalu turunin tiap atribut pakai EXTRACT dan TO_CHAR. EXTRACT ngambil angka kayak tahun, bulan, dan kuartal. TO_CHAR ngasih teks kayak nama hari dan nama bulan. Satu perintah INSERT bisa ngisi ribuan baris sekaligus. Buat MySQL yang nggak punya generate_series, pakai recursive CTE dulu buat bikin deret tanggalnya.
Gimana cara pakai tabel kalender di query laporan?
JOIN tabel fakta (misalnya transaksi) ke tabel kalender lewat kolom tanggal, lalu GROUP BY atribut yang kamu mau. Contohnya buat omzet per kuartal, JOIN transaksi ke dim_tanggal lalu GROUP BY kuartal. Karena atributnya udah tersedia, kamu nggak perlu nulis EXTRACT di query laporan. Ini bikin query jauh lebih pendek dan seragam antar anggota tim.
Apa beda tabel kalender dengan deret tanggal biasa?
Deret tanggal cuma satu kolom berisi tanggal berurutan, dibuat sekali pakai untuk kebutuhan sesaat kayak ngisi hari kosong. Tabel kalender permanen dan punya banyak kolom atribut per tanggal. Kalau kamu cuma butuh isi tanggal kosong sekali, deret tanggal cukup. Kalau atribut tanggal dipakai berulang di banyak laporan, tabel kalender jauh lebih hemat dan konsisten.
Latihan sekarang
- Tabel kalender nyimpen atribut tanggal sekali, lalu di-JOIN ke tabel fakta biar laporan nggak ngitung ulang.
- Isi pakai generate_series plus EXTRACT dan TO_CHAR di PostgreSQL, atau recursive CTE di MySQL.
- Jadikan kolom tanggal PRIMARY KEY, dan isi rentang beberapa tahun ke depan sekaligus.
Coba sekarang: bikin dim_tanggal buat 2024 sampai 2030, lalu JOIN ke data penjualanmu buat laporan per kuartal. Latihan langsung bisa kamu lakuin di NgulikSQL. Lanjut ke CROSS JOIN SQL kalau kamu mau gabungin tabel kalender dengan daftar produk atau cabang buat kerangka laporan lengkap.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel terkait
Composite Index di SQL: Cara Kerja dan Urutan Kolom
Composite index itu index atas beberapa kolom sekaligus. Urutan kolomnya nentuin query mana yang kebantu, lewat aturan leftmost prefix.
Menghitung Stickiness (DAU/MAU) di SQL
Stickiness ngukur seberapa sering user balik lagi. Ini cara hitung DAU, MAU, dan rasio stickiness pakai SQL, plus contoh aplikasi UMKM.
Menghitung DAU dan MAU dengan SQL
DAU dan MAU dua metrik wajib buat produk digital. Ini cara hitungnya pakai SQL, lengkap query DISTINCT, per bulan, sampai rasio stickiness.