Ana içeriğe geç
Kesit SQL
Orta · İleri Sorgu Yapıları

Tarih serisi ve takvim tablosu: eksik günleri doldurmak

Özyinelemeli CTE, GENERATE_SERIES ve LEFT JOIN ile boşluksuz zaman serisi.

Uygulamada aç, 8 alıştırmayı çözÜcretsiz, hesap gerekmez, kurulum yok.

Bu sayfa dersin okuma sürümüdür. Metin bir kutuyu çalıştırmanı ya da adıma geçmeni söylüyorsa dersi uygulamada aç.

Sipariş olmayan gün raporda kaybolur

Günlük sipariş sayısını GROUP BY order_date ile alırsan, hiç sipariş olmayan günler sonuçta hiç görünmez. Grafikte bu günler atlanır ve trend olduğundan iyi görünür. Çözüm: önce eksiksiz bir gün listesi üret, sonra veriyi ona LEFT JOIN ile bağla.

1. Özyinelemeli CTE ile gün listesi (her SQL türünde)

WITH RECURSIVE gunler(gun) AS (
    SELECT DATE('2024-12-01')
    UNION ALL
    SELECT DATE(gun, '+1 day') FROM gunler WHERE gun < '2024-12-31'
)
SELECT g.gun,
       COUNT(o.order_id) AS siparis
FROM gunler g
LEFT JOIN orders o ON o.order_date = g.gun
GROUP BY g.gun
ORDER BY g.gun;
SQL Server'da özyineleme sınırıSQL Server varsayılan olarak en fazla 100 tur özyinelemeye izin verir. Bir yıllık seri (365 gün) için sorgunun sonuna OPTION (MAXRECURSION 0) eklemelisin.

2. Hazır seri fonksiyonları

SQL Server 2022 ve PostgreSQL seri üreten fonksiyonlara sahiptir; Oracle'da klasik yöntem CONNECT BY LEVEL'dır:

SELECT DATEADD(day, value, '2024-12-01') AS gun
FROM GENERATE_SERIES(0, 6);
-- Oracle
SELECT DATE '2024-12-01' + LEVEL - 1 AS gun
FROM dual
CONNECT BY LEVEL <= 7;

Takvim (tarih boyutu) tablosu

Raporlama yapılan her veritabanında genellikle kalıcı bir takvim tablosu bulunur: her gün için bir satır ve hazır hesaplanmış sütunlar. Böylece “hafta sonu mu?”, “hangi çeyrek?”, “resmî tatil mi?” soruları her sorguda yeniden hesaplanmaz.

WITH RECURSIVE gunler(gun) AS (
    SELECT DATE('2024-12-01')
    UNION ALL
    SELECT DATE(gun, '+1 day') FROM gunler WHERE gun < '2024-12-31'
)
SELECT gun,
       CAST(strftime('%Y', gun) AS INTEGER) AS yil,
       CAST(strftime('%m', gun) AS INTEGER) AS ay,
       CAST(strftime('%w', gun) AS INTEGER) AS haftanin_gunu,
       CASE WHEN CAST(strftime('%w', gun) AS INTEGER) IN (0, 6) THEN 1 ELSE 0 END AS hafta_sonu
FROM gunler;
Takvim tablosuna eklenebileceklerResmî tatiller, mali yıl/çeyrek, ISO hafta numarası, ayın son iş günü, kampanya dönemleri. BI araçlarında (Power BI, Tableau) bu tablo “Date” boyutu olarak modele bağlanır.
Alıştırmalara geç (8)