Yöneticinin üç sorusu
- YTD (year to date): Yıl başından bugüne ne kadar sattık?
- MTD / QTD: Ay ya da çeyrek başından bugüne?
- YoY (year over year): Geçen yılın aynı dönemine göre ne değişti?
Önce aylık ciroyu bir CTE'de hesaplayıp, YTD'yi pencere fonksiyonuyla, geçen yılı ise CTE'yi kendisiyle birleştirerek buluruz.
WITH aylik AS (
SELECT CAST(strftime('%Y', o.order_date) AS INTEGER) AS yil,
CAST(strftime('%m', o.order_date) AS INTEGER) AS ay,
SUM(oi.quantity * oi.unit_price * (1 - oi.discount)) AS ciro
FROM orders o
JOIN order_items oi ON oi.order_id = o.order_id
WHERE o.status = 'delivered'
GROUP BY CAST(strftime('%Y', o.order_date) AS INTEGER),
CAST(strftime('%m', o.order_date) AS INTEGER)
)
SELECT yil, ay,
ROUND(ciro, 0) AS ciro,
ROUND(SUM(ciro) OVER (PARTITION BY yil ORDER BY ay), 0) AS ytd
FROM aylik
WHERE yil = 2024
ORDER BY ay;
Geçen yılın aynı ayı
LAG(ciro, 12) pratik görünür ama arada satırı olmayan bir ay varsa yanlış aya kayar. Yıl ve ay üzerinden kendine birleştirme daha güvenlidir:
WITH aylik AS (
SELECT CAST(strftime('%Y', o.order_date) AS INTEGER) AS yil,
CAST(strftime('%m', o.order_date) AS INTEGER) AS ay,
SUM(oi.quantity * oi.unit_price * (1 - oi.discount)) AS ciro
FROM orders o
JOIN order_items oi ON oi.order_id = o.order_id
WHERE o.status = 'delivered'
GROUP BY CAST(strftime('%Y', o.order_date) AS INTEGER),
CAST(strftime('%m', o.order_date) AS INTEGER)
)
SELECT b.ay,
ROUND(b.ciro, 0) AS ciro_2024,
ROUND(a.ciro, 0) AS ciro_2023,
ROUND(100.0 * (b.ciro - a.ciro) / a.ciro, 1) AS degisim
FROM aylik b
LEFT JOIN aylik a ON a.yil = b.yil - 1 AND a.ay = b.ay
WHERE b.yil = 2024
ORDER BY b.ay;
“Bugün” tuzağıYTD raporunu
GETDATE() / CURRENT_DATE ile yazarsan, geçen yılın YTD'sini de aynı gün ve aya kadar kesmelisin; yoksa eksik bir yılı tam bir yılla kıyaslarsın. Raporlarda tarihi bir parametre olarak almak en temiz yoldur.