Membuat Tabel Kalender (Date Dimension) di SQL
Blog/Tutorial SQL/Membuat Tabel Kalender (Date Dimension) di SQL

Membuat Tabel Kalender (Date Dimension) di SQL

BimaBima
·25 Agustus 2026·9 menit baca

Penulis

Bima

Bima

Founder & Data Professional

Bagikan

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.

KolomIsiContoh
tanggalKunci utama, tanggal murni2026-08-25
tahunTahun 4 digit2026
bulanBulan angka8
nama_bulanNama bulan teksAgustus
kuartalKuartal 1 sampai 43
nama_hariNama hari teksSelasa
is_weekendPenanda akhir pekanfalse

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.

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

Composite Index di SQL: Cara Kerja dan Urutan Kolom
Tutorial SQL
8 Oktober 2026•8 menit baca

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.

BimaBima
Menghitung Stickiness (DAU/MAU) di SQL
Tutorial SQL
5 Oktober 2026•10 menit baca

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.

BimaBima
Menghitung DAU dan MAU dengan SQL
Tutorial SQL
3 Oktober 2026•9 menit baca

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.

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.

© 2026 Ngulik Data. Semua hak dilindungi.

TAUTAN
BantuanHargaDatasetBlogAfiliasi
LEGAL
Syarat & KetentuanKebijakan Privasi
Ngulik Data
DatasetLeaderboardBlogStore