فصل 33 از 50 درس 1 از 1

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 و ویژگی‌های موردنیاز کسب‌وکار را به آن اضافه کن.

شکل ۳۳-۱ — Time Intelligence از Date Table و Relationship درست شروع می‌شود
شکل ۳۳-۱ — Time Intelligence از Date Table و Relationship درست شروع می‌شود

۳۳.۲. ساخت 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])

۳۳.۱۶. منطق رشد

شکل ۳۳-۲ — ابتدا دوره جاری و قبلی را می‌سازیم، سپس Variance و Growth % را محاسبه می‌کنیم
شکل ۳۳-۲ — ابتدا دوره جاری و قبلی را می‌سازیم، سپس Variance و Growth % را محاسبه می‌کنیم

۳۳.۱۷. 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 کسب‌وکار

ستوننمونه
FiscalYearFY2026
FiscalMonthNo1..12
FiscalQuarterFQ1
IsWorkingDayTrue/False
WeekOfYear1..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

KPIMeasure
CurrentTotal Sales
Previous MonthSales Previous Month
VarianceMoM Growth
Variance %MoM Growth %
YTDSales YTD
PY YTDSales 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 شرکت هانا

خروجیشرح
DimDateCalendar + business attributes
MTD/QTD/YTDCurrent cumulative
PY/PMPrevious periods
GrowthAbsolute + percentage
Rolling90D + 12M
Date RolesOrder/Ship
FreshnessLast data date
QAPartial-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 و شناسایی بهترین و ضعیف‌ترین محصولات و مشتریان.