Session 33 — Time Intelligence حرفهای در Power BI؛ Date Table، YTD/MTD/QTD و مقایسههای زمانی
Time Intelligence حرفهای در Power BI؛ Date Table، YTD/MTD/QTD و مقایسههای زمانی
بخشی از آموزش جامع Power BI
محتوای درس Time Intelligence حرفهای در Power BI؛ Date Table، YTD/MTD/QTD و مقایسههای زمانی
شروع جلسه؛ «فروش امسال» به تنهایی کافی نیست
مدیر معمولاً فقط نمیپرسد چقدر فروختیم؛ میپرسد نسبت به ماه قبل چی؟ نسبت به پارسال؟ تا امروز سال چقدر؟ رشد چند درصد بوده؟ همین سؤالها ما را وارد Time Intelligence میکنند.
Time Intelligence وقتی قابل اعتماد است که مدل زمانی درست داشته باشیم؛ فرمول خوب روی Date Model خراب، جواب قابل اعتماد نمیدهد.
۳۳.۱. پایه کار؛ Date Table
یک جدول تاریخ پیوسته بساز که هر روز بازه تحلیلی را داشته باشد. Year، Quarter، Month، MonthNumber، Week و ویژگیهای موردنیاز کسبوکار را به آن اضافه کن.
۳۳.۲. ساخت Date Table با DAX
DimDate =
ADDCOLUMNS(
CALENDAR(DATE(2024,1,1), DATE(2027,12,31)),
"Year", YEAR([Date]),
"MonthNo", MONTH([Date]),
"Month", FORMAT([Date], "MMMM"),
"Quarter", "Q" & FORMAT([Date], "Q")
)
۳۳.۳. CALENDARAUTO
DimDate = CALENDARAUTO()
برای شروع سریع مفید است، ولی در پروژه سازمانی بازه تاریخ را آگاهانه کنترل کن.
۳۳.۴. Mark as Date Table
در مدلهایی که نیازمند قابلیتهای کلاسیک Time Intelligence هستند، Date Table استاندارد و ستون Date معتبر داشته باش و تنظیمات Date Table را درست انجام بده.
۳۳.۵. Relationship تاریخ
DimDate[Date] 1 → * FactSales[OrderDate]
فیلتر تاریخ باید از Dimension Date به Fact منتقل شود.
۳۳.۶. ستون Date با DateTime
اگر Fact شامل DateTime است ولی DimDate فقط Date دارد، قبل از Relationship سطح زمانی را درست طراحی کن؛ ساعت را بیدلیل وارد کلید روز نکن.
۳۳.۷. Sort Month
MonthName را با MonthNumber مرتب کن تا ترتیب ماهها تقویمی باشد، نه الفبایی.
۳۳.۸. Measure پایه
Total Sales = SUM(FactSales[SalesAmount])
Time Intelligence را روی Measure پایه میسازیم، نه اینکه منطق فروش را در هر Measure دوباره تکرار کنیم.
۳۳.۹. YTD چیست؟
Year-to-Date یعنی از ابتدای سال تا آخرین تاریخ موجود در Context فعلی.
۳۳.۱۰. TOTALYTD
Sales YTD =
TOTALYTD(
[Total Sales],
DimDate[Date]
)
۳۳.۱۱. DATESYTD
Sales YTD =
CALCULATE(
[Total Sales],
DATESYTD(DimDate[Date])
)
۳۳.۱۲. MTD
Sales MTD =
TOTALMTD(
[Total Sales],
DimDate[Date]
)
۳۳.۱۳. QTD
Sales QTD =
TOTALQTD(
[Total Sales],
DimDate[Date]
)
۳۳.۱۴. Previous Year
Sales PY =
CALCULATE(
[Total Sales],
SAMEPERIODLASTYEAR(DimDate[Date])
)
۳۳.۱۵. رشد سالانه
YoY Growth = [Total Sales] - [Sales PY]
YoY Growth % = DIVIDE([YoY Growth], [Sales PY])
۳۳.۱۶. منطق رشد
۳۳.۱۷. DATEADD
Sales Previous Month =
CALCULATE(
[Total Sales],
DATEADD(DimDate[Date], -1, MONTH)
)
۳۳.۱۸. رشد ماهانه
MoM Growth = [Total Sales] - [Sales Previous Month]
MoM Growth % = DIVIDE([MoM Growth], [Sales Previous Month])
۳۳.۱۹. Previous Quarter
Sales Previous Quarter =
CALCULATE(
[Total Sales],
DATEADD(DimDate[Date], -1, QUARTER)
)
۳۳.۲۰. چرا Date Context مهم است؟
اگر Visual ماه فروردین را نشان دهد، Previous Month باید Context زمانی را به ماه قبل منتقل کند. این همان قدرت Date Table + CALCULATE است.
۳۳.۲۱. DATESBETWEEN
Sales Custom Period =
CALCULATE(
[Total Sales],
DATESBETWEEN(
DimDate[Date],
DATE(2026,1,1),
DATE(2026,6,30)
)
)
۳۳.۲۲. DATESINPERIOD
Sales Rolling 90 Days =
CALCULATE(
[Total Sales],
DATESINPERIOD(
DimDate[Date],
MAX(DimDate[Date]),
-90,
DAY
)
)
۳۳.۲۳. Rolling Period
Rolling 30/90/365 Days برای تحلیل روند مفید است چون محدود به مرز ماه یا سال نیست.
۳۳.۲۴. Rolling 12 Months
Sales Rolling 12M =
CALCULATE(
[Total Sales],
DATESINPERIOD(
DimDate[Date],
MAX(DimDate[Date]),
-12,
MONTH
)
)
۳۳.۲۵. Running Total
Sales Running Total =
VAR MaxDate = MAX(DimDate[Date])
RETURN
CALCULATE(
[Total Sales],
FILTER(
ALL(DimDate[Date]),
DimDate[Date] <= MaxDate
)
)
۳۳.۲۶. YTD و Running Total یکی نیستند
YTD در ابتدای سال Reset میشود؛ Running Total عمومی میتواند از ابتدای کل بازه مدل ادامه پیدا کند.
۳۳.۲۷. Fiscal Year
اگر سال مالی شرکت از ژانویه شروع نمیشود، Time Intelligence باید بر اساس Calendar کسبوکار طراحی شود؛ Year-to-Date کسبوکار الزاماً Calendar YTD نیست.
۳۳.۲۸. Calendar کسبوکار
| ستون | نمونه |
|---|---|
| FiscalYear | FY2026 |
| FiscalMonthNo | 1..12 |
| FiscalQuarter | FQ1 |
| IsWorkingDay | True/False |
| WeekOfYear | 1..53 |
۳۳.۲۹. تقویم شمسی
در پروژه فارسی ممکن است نمایش و گزارش بر اساس سال/ماه شمسی لازم باشد. بهتر است ستونهای شمسی استاندارد در Date Dimension تولید شوند و ترتیب عددی ماه/سال نیز جدا نگهداری شود.
۳۳.۳۰. نکته تقویم شمسی
توابع کلاسیک Time Intelligence DAX حول Date واقعی مدل کار میکنند. برای نمایش شمسی، Date واقعی را حفظ و ویژگیهای شمسی را به Dimension اضافه کن؛ منطق Fiscal/شمسی خاص را بر اساس نیاز سازمان تست کن.
۳۳.۳۱. روز کاری
مقایسه فروش تا روز دهم این ماه با کل ماه قبل ممکن است گمراهکننده باشد. گاهی باید تعداد روز کاری یا Same-Day-of-Period را در تحلیل لحاظ کنیم.
۳۳.۳۲. Partial Period Problem
اگر امروز روز ۲۰ ماه است، مقایسه MTD جاری با کل ماه قبلی منصفانه نیست. باید مشخص کنیم مقایسه با MTD ماه قبل تا روز متناظر است یا کل ماه قبل.
۳۳.۳۳. Previous MTD
Sales Previous MTD =
CALCULATE(
[Sales MTD],
DATEADD(DimDate[Date], -1, MONTH)
)
۳۳.۳۴. YTD پارسال
Sales PY YTD =
CALCULATE(
[Sales YTD],
SAMEPERIODLASTYEAR(DimDate[Date])
)
۳۳.۳۵. YTD Growth
YTD Growth = [Sales YTD] - [Sales PY YTD]
YTD Growth % = DIVIDE([YTD Growth], [Sales PY YTD])
۳۳.۳۶. Max Data Date
Last Sales Date = MAX(FactSales[OrderDate])
برای Dashboard عملیاتی مهم است بدانیم آخرین داده واقعی مربوط به چه تاریخی است.
۳۳.۳۷. Data Freshness
Data Freshness Days =
DATEDIFF([Last Sales Date], TODAY(), DAY)
۳۳.۳۸. TODAY و Refresh
در Service و Refresh زمانبندیشده، رفتار تاریخ/زمان و منطقه زمانی را در معماری Deployment بررسی کن؛ بهخصوص وقتی KPI به «امروز» وابسته است.
۳۳.۳۹. Sales Today
Sales Today =
CALCULATE(
[Total Sales],
DimDate[Date] = TODAY()
)
۳۳.۴۰. Sales Yesterday
Sales Yesterday =
CALCULATE(
[Total Sales],
DimDate[Date] = TODAY() - 1
)
۳۳.۴۱. Week Analysis
تعریف هفته در سازمانها متفاوت است؛ شنبه تا جمعه، دوشنبه تا یکشنبه یا ISO Week. این تعریف باید در DimDate صریح باشد.
۳۳.۴۲. Week-over-Week
برای WoW اول باید Week Key استاندارد داشته باشی و مشخص باشد هفته جاری ناقص چگونه مقایسه میشود.
۳۳.۴۳. Multiple Date Roles
FactSales ممکن است OrderDate، InvoiceDate و ShipDate داشته باشد. Date Dimension یکسان است ولی نقشها متفاوتاند.
۳۳.۴۴. USERELATIONSHIP
Sales by Ship Date =
CALCULATE(
[Total Sales],
USERELATIONSHIP(
FactSales[ShipDate],
DimDate[Date]
)
)
۳۳.۴۵. Ship Date YTD
Ship Sales YTD =
CALCULATE(
[Total Sales],
DATESYTD(DimDate[Date]),
USERELATIONSHIP(FactSales[ShipDate], DimDate[Date])
)
۳۳.۴۶. Date Role باید در اسم Measure روشن باشد
Total Sales by Order Date و Sales by Ship Date دو معنی متفاوت دارند. Naming باید جلوی سوءبرداشت را بگیرد.
۳۳.۴۷. Target و Time
اگر Target ماهانه است، Actual روزانه را میتوان در سطح ماه با Target مقایسه کرد. اما Daily Target نیازمند Rule تخصیص است و نباید خودسرانه Target ماه را تقسیم بر ۳۰ کنیم.
۳۳.۴۸. Target YTD
Target YTD =
TOTALYTD(
[Target],
DimDate[Date]
)
۳۳.۴۹. YTD Achievement
YTD Achievement % =
DIVIDE([Sales YTD], [Target YTD])
۳۳.۵۰. Dynamic Period Label
Period Label =
VAR MinDate = MIN(DimDate[Date])
VAR MaxDate = MAX(DimDate[Date])
RETURN
FORMAT(MinDate,"yyyy-MM-dd") & " تا " & FORMAT(MaxDate,"yyyy-MM-dd")
۳۳.۵۱. Current vs Previous KPI
| KPI | Measure |
|---|---|
| Current | Total Sales |
| Previous Month | Sales Previous Month |
| Variance | MoM Growth |
| Variance % | MoM Growth % |
| YTD | Sales YTD |
| PY YTD | Sales PY YTD |
۳۳.۵۲. پروژه شرکت هانا؛ Executive Time KPIs
Total Sales
Sales MTD
Sales Previous MTD
MoM Growth %
Sales YTD
Sales PY YTD
YTD Growth %
Sales Rolling 12M
۳۳.۵۳. Visual پیشنهادی
بالای Dashboard چهار Card برای Sales MTD، MoM Growth %، Sales YTD و YTD Growth % قرار بده. پایین آن Trend ماهانه Current vs Previous Year و Rolling 12M را نمایش بده.
۳۳.۵۴. Tooltips زمانی
در Tooltip میتوان Current Sales، Previous Period، Variance و Growth % را کنار هم نشان داد تا کاربر دلیل رنگ KPI را بفهمد.
۳۳.۵۵. Conditional Formatting
رشد مثبت/منفی را با Rule کسبوکار Format کن. همیشه مثبت بودن رشد به معنی خوب بودن نیست؛ مثلاً Cost یا Defect Rate برعکس است.
۳۳.۵۶. خطای رایج؛ Date از Fact
استفاده مستقیم از چند ستون تاریخ Fact در Visualها بدون Date Dimension منسجم، Time Intelligence را شکننده میکند.
۳۳.۵۷. خطای رایج؛ Date Table ناقص
اگر روزهایی که فروش ندارند از Date Table حذف شوند، تحلیل روند و مقایسههای زمانی میتواند مشکل پیدا کند. Date Dimension باید پیوسته باشد.
۳۳.۵۸. خطای رایج؛ Month Name بدون Year
اگر فقط MonthName روی محور باشد، January چند سال با هم ترکیب میشود. Month-Year یا Hierarchy مناسب استفاده کن.
۳۳.۵۹. خطای رایج؛ مقایسه دوره ناقص
MTD روز دهم را با کل ماه قبل مقایسه نکن مگر اینکه دقیقاً همین KPI مدنظر باشد.
۳۳.۶۰. خطای رایج؛ رشد با Previous=0
وقتی دوره قبلی صفر یا Blank است، Growth % نیازمند Rule مشخص کسبوکار است. DIVIDE از خطای تقسیم جلوگیری میکند ولی معنی KPI را تو باید تعریف کنی.
۳۳.۶۱. خطای رایج؛ TODAY بدون توجه به داده
ممکن است امروز ۲۰ام باشد ولی داده فقط تا ۱۸ام Load شده باشد. Current Period را گاهی باید بر اساس Last Data Date تعریف کرد، نه صرفاً TODAY.
۳۳.۶۲. Last Data Date Context
در Dashboard سازمانی میتوان عنوانی مثل «دادهها تا تاریخ ...» نمایش داد تا مدیر بداند KPI چقدر تازه است.
۳۳.۶۳. Performance
Time Intelligence روی مدل Star Schema و Date Dimension کمحجم معمولاً بسیار قابل مدیریت است. پیچیدگی بیدلیل Virtual Tableها را فقط وقتی نیاز است اضافه کن.
۳۳.۶۴. Best Practiceها
Date Table پیوسته و استاندارد بساز.
Date واقعی را حتی در گزارش شمسی حفظ کن.
Month را با MonthNumber Sort کن.
Measure پایه را یک بار تعریف کن.
Current و Previous Period را جدا بساز.
Variance و Growth % را از Measureهای پایه Branch کن.
دوره ناقص را آگاهانه مقایسه کن.
Roleهای مختلف Date را نامگذاری کن.
Last Data Date را در Dashboardهای عملیاتی نمایش بده.
۳۳.۶۵. تمرین ۱
Sales MTD، QTD و YTD را بساز و در Matrix Year → Month رفتارشان را بررسی کن.
۳۳.۶۶. تمرین ۲
Sales PY، YoY Growth و YoY Growth % را بساز و Totalها را Validate کن.
۳۳.۶۷. تمرین ۳
Sales Previous Month و MoM Growth % را بساز. سپس ماهی که دوره قبلی فروش صفر دارد بررسی کن.
۳۳.۶۸. تمرین ۴
Rolling 90 Days و Rolling 12 Months بساز و تفاوت آنها را با YTD توضیح بده.
۳۳.۶۹. تمرین ۵
Sales by Ship Date و Ship Sales YTD را با USERELATIONSHIP پیادهسازی کن.
۳۳.۷۰. تمرین چالشی
یک KPI طراحی کن که MTD جاری را با MTD ماه قبل تا روز متناظر مقایسه کند و بر اساس Last Data Date از مقایسه ناعادلانه جلوگیری کند.
۳۳.۷۱. پروژه Session؛ Time Intelligence Pack شرکت هانا
| خروجی | شرح |
|---|---|
| DimDate | Calendar + business attributes |
| MTD/QTD/YTD | Current cumulative |
| PY/PM | Previous periods |
| Growth | Absolute + percentage |
| Rolling | 90D + 12M |
| Date Roles | Order/Ship |
| Freshness | Last data date |
| QA | Partial-period validation |
در پایان باید مدیر بتواند در یک صفحه ببیند الان کجاییم، نسبت به دوره قبل چه تغییری کردهایم و آیا مقایسه از نظر زمانی منصفانه است یا نه.
جمعبندی Session 33
Time Intelligence خوب فقط نوشتن TOTALYTD نیست؛ ترکیب Date Model درست، Context درست و تعریف کسبوکاری درست از «دوره قابل مقایسه» است.
Reliable Date Model + Base Measures + Comparable Periods = Trustworthy Time Intelligence
Session 34 را وارد Ranking و Top N میکنیم: RANKX، TOPN، Pareto 80/20، ABC Analysis و شناسایی بهترین و ضعیفترین محصولات و مشتریان.