SQL TARİH BOYUTU MANTIĞI
SQL ile raporlama yapan bir analist tarihle ilgili soruların ne kadar tuhaflaştığını çabuk fark eder. "Geçen ayın aynı haftası", "geçen yılın aynı çeyreği", "mali yıl başından beri", "iş günü sayısı", "tatil günleri hariç". Bu soruların her biri ham tarihten doğrudan çıkarılmaya çalışıldığında sorgu giderek karmaşıklaşır. Tarih boyutu tablosu bu karmaşıklığı kökten çözer; tarih hakkında bilmek istediğiniz her şeyi önceden hesaplayıp tek bir tabloda tutmaktır.
Tarih Boyutu Nedir
Tarih boyutu (date dimension) tipik olarak her tarihin bir satır olduğu bir tablodur. 2020-01-01 ile 2030-12-31 arası tüm günler için bir satır vardır, yaklaşık dört bin satırdır. Her satırda o tarihin tüm özellikleri kolon olarak durur:
- Takvim kolonları: gün, ay, yıl, çeyrek, hafta, hafta günü.
- Metin kolonları: ay adı, hafta günü adı, kısa tarih etiketi (2026-05).
- Bayraklar: hafta_sonu_mu, tatil_mi, is_gunu_mu, ay_sonu_mu, yil_sonu_mu.
- Mali takvim: mali_yil, mali_ceyrek, mali_ay.
- Sayaçlar: yilbasindan_gun, ay_basindan_gun, ceyrek_basindan_gun.
- Karşılaştırma anahtarları: gecen_yil_ayni_gun, gecen_ay_ayni_gun.
Bu zenginlik sayesinde herhangi bir tarih sorusu artık karmaşık DATE fonksiyon yazımına gerek kalmadan basit bir JOIN ile cevaplanır.
Bir satış tablosu tarih boyutuna satış tarihi üzerinden bağlanır. "Ocak ayındaki satışlar" sorgusu tarih tablosundan ay = 1 olan satırları alır, satış tablosuyla birleştirir, toplamı çeker. DATEPART veya MONTH fonksiyonu kullanılmadan, performans avantajıyla, tutarlı sonuçlarla.

Neden Tarih Fonksiyonu Yerine Tablo
Tarih fonksiyonları her veritabanında farklıdır. SQL Server'da DATEPART, PostgreSQL'de EXTRACT, MySQL'de YEAR ve MONTH ayrı ayrı çağrılır. Bu durum sorguları taşınmaz kılar ve farklı motorlarda farklı yazımlar bilinmesini gerektirir. Tarih boyutu kullanıldığında sorgular standart SQL JOIN'leri olur ve her veritabanında aynı çalışır.
Daha kritiği, tarih hakkındaki iş mantıkları (mali yıl, çeyrek, tatil) fonksiyonla ifade edilemez. Türkiye'de mali yıl 1 Ocak'ta başlar ama birçok kurumda dahili mali çeyrek tanımı farklıdır. Tatiller her yıl değişir; 23 Nisan sabit bir tatildir ama Ramazan ve Kurban Bayramı kayar. Bu tip iş kurallarını sorgu içinde her seferinde yazmak yerine tarih tablosunda kolonlara koymak çok daha kalıcıdir.
Tarih Tablosunun Oluşturulması
Tarih tablosu genellikle bir kez yaratılır ve veritabanında durur. Yaratmanın klasik yolu recursive CTE veya rakam tablosu kullanmaktır. SQL Server'da rakam tablosu yardımıyla aşağıdaki gibi bir mantık çalışır: 0'dan başlayan bir sayı dizisi üret, başlangıç tarihine bu sayıları gün olarak ekle, çıkan her tarih için ek kolonları hesapla. Bu işlem birkaç saniyede tamamlanır ve tablo on yıllık tarih için yaklaşık 3.650 satır içerir.
Tablo bir kez oluşturulduktan sonra üzerine her zaman yeni kolonlar eklenebilir. Yeni bir iş ihtiyacı geldiğinde — örneğin bütçe dönemi farklı tanımlanırsa — bu kolon tabloya eklenir, tüm sorgular bunu otomatik kullanmaya başlar. Bu esneklik tarih boyutunun büyük gücüdür.
Mali Yıl ve Çeyrek
Bazı kurumlarda mali yıl 1 Ocak'tan başlamaz; örneğin Temmuz'dan başlayan mali yıl yaygındır. Bu durumda mali yıl kolonu takvim yılından farklı olur. 2025 Temmuz - 2026 Haziran arası "mali 2026" olarak işaretlenir. Mali çeyrek de aynı mantıkla hesaplanır: mali yılın ilk üç ayı Q1, sonraki üç ay Q2 gibi.
Mali takvim raporda kullanılınca sorgu yazmak kolaylaşır. Adım adım uygulanışı Wikipedia'nın SQL sayfasında açıklanır. "Mali 2026 Q1 satışları" istendiğinde sadece tarih tablosundan mali_yil = 2026 AND mali_ceyrek = 1 filtrelenir; karmaşık CASE WHEN ifadeleri olmadan doğru aralık seçilir.
Yıldan Yıla ve Aydan Aya Karşılaştırma
YoY (yıldan yıla) ve MoM (aydan aya) karşılaştırmaları yönetici raporlarının temel direğidir. Tarih tablosuyla bu karşılaştırmalar oldukça düzgün yazılır. Bir yaklaşım her satışı kendi tarihinden bir yıl önceki tarihle eşlemektir; tarih boyutuna geçen yıl aynı gün kolonu eklenir. Sorguda satış tablosu iki kez kullanılır; biri cari dönem, biri geçen yıl aynı dönem; sonuçlar yan yana getirilip karşılaştırılır.
Daha pratik bir yaklaşım pencere fonksiyonu kullanmaktır. LAG fonksiyonu önceki satıra bakar; ay bazında sıralanmış satış toplamlarında LAG(toplam, 12) geçen yılın aynı ayındaki değeri döner. Aradaki farkı veya yüzde değişimi tek sorguyla hesaplamak mümkün olur. Bu yöntemin koşulu her ay için bir satır olmasıdır; yoksa LAG yanlış değer döner.
İş Günü Sayısı
"Bu ayın ilk on iş günündeki satış" gibi sorular tarih tablosu olmadan oldukça çirkin yazılır. Tarih tablosu varsa basittir: tarih tablosunda is_gunu = 1 ve yil = 2026 AND ay = 5 satırlardan ilk on tanesini al, satış tablosuyla birleştir. Tatil günleri ve hafta sonları otomatik dışlanır çünkü bu bilgi tarih tablosunda zaten kolon olarak vardır.
Aynı mantık "ilerleme yüzdesi" tipi raporlarda da işe yarar. Mayıs ayının yarısı geçmiş olabilir ama iş günü olarak %60'ı geçmiş olabilir; bu fark tarih tablosundaki iş günü sayımıyla hesaplanır.
Tipik bir YoY karşılaştırması tarih boyutu kullanılarak şöyle yazılır:
SELECT
d.yil,
d.ay,
d.ay_adi,
SUM(s.tutar) AS bu_yil,
LAG(SUM(s.tutar), 12) OVER (ORDER BY d.yil, d.ay) AS gecen_yil,
SUM(s.tutar) - LAG(SUM(s.tutar), 12) OVER (ORDER BY d.yil, d.ay) AS fark,
(SUM(s.tutar) * 1.0 / LAG(SUM(s.tutar), 12) OVER (ORDER BY d.yil, d.ay) - 1) * 100 AS yuzde_degisim
FROM satislar s
JOIN tarih_boyutu d ON s.tarih = d.tarih
WHERE d.yil BETWEEN 2025 AND 2026
GROUP BY d.yil, d.ay, d.ay_adi
ORDER BY d.yil, d.ay;
Tatil Tablosunun Bakımı
Tarih tablosunun en bakım gerektiren kısmı tatil bilgisidir. Sabit tatiller bir kez girilir ve unutulur, ama kayan tatiller (Ramazan Bayramı, Kurban Bayramı) her yıl güncellenmesi gerekir. Genellikle yıl başında o yılın tatil takvimi tabloya işlenir. Bu küçük bakım unutulursa rapor yıl sonuna doğru hatalı iş günü sayımı vermeye başlar.
Bazı kurumlar tatil tablosunu ayrı tutup tarih boyutuna LEFT JOIN ile bağlamayı tercih eder. Bu yapı tatillerin değişiminden tarih tablosunu izole eder; tatil tablosu güncellendiğinde tarih tablosu hesaplamaları otomatik takip eder.
Power BI ve Excel ile Uyum
SQL'deki tarih boyutu Power BI'da olduğu gibi kullanılabilir. Power BI'ın time intelligence fonksiyonları doğru tarih boyutu olmadan çalışmaz; tablonun mark as date table olarak işaretlenmesi gerekir. Excel'in pivot tablolarında da tarih boyutuyla çalışmak takvim açısından doğru karşılaştırmalar sağlar.
Tarih boyutu olmayan bir veri ambarı çok hızlı raporlama kısıtlarına çarpar. SQL eğitimi bu yapının nasıl kurulduğunu, sürdürüldüğünü ve raporlama mantığıyla nasıl kullanıldığını ayrıntılı işler.
Sıkça Sorulan Sorular
Tarih boyutu her veritabanında olmalı mı?
Raporlama yapılan her veri ambarında olmalı. İşlem (OLTP) veritabanlarında genellikle gerekmez, raporlama tarafında zorunluluktur.
Kaç yıllık veri içermeli?
Mevcut veriden beş yıl önceden ve beş yıl sonrasına kadar tipik olarak yeterlidir. Daha az olursa eski raporlar için tarih bulamaz; daha fazla olursa gereksiz şişer.
Tarih tablosu indeks ister mi?
Birincil anahtar olarak tarih kolonu üzerine kümelenmiş indeks yeterlidir. Yıl, ay, çeyrek gibi sık filtrelenen kolonlara ek indeks koymak performansı iyileştirir.
Saat dahil tarih için ne yapılır?
Tarih boyutu gün seviyesinde tutulur, saat ayrı bir boyut olarak kurulur. Saat seviyesinde rapor gerekiyorsa zaman boyutu (24 satırlık veya 1440 satırlık) eklenir.
Mali yıl her ay başlayabilir mi?
Teknik olarak evet ama tek bir mali yıl başlangıcı seçilmesi tutarlılık açısından zorunludur. İki farklı mali yıl tanımı varsa her birine ayrı kolon eklenir.
Tarih boyutu olmadan da olur mu?
Olur ama her tarih sorusunda farklı yazılır, performans kaybı olur ve mali yıl gibi iş kuralları sorgu içinde dağılır. Pratikte raporlama ekosistemi tarih boyutu olmadan ölçeklenmez.



