作為一名資深資料打撈師,每當遇到要計算 YoY 成長百分比這類的需求,就會開啟地獄級的 SQL 編碼過程。如果有人問我為什麼這麼喜歡 Power BI,我會說是因為 DAX 的強大,其中最厲害的應該是時間智慧函數,因為他解決了這個 SQL 很難解決的問題。
要使用時間智慧函數有個很大的前提:資料模型中必須要有 日期
這個維度,這個大前提又印證了使用 DAX 前請先學好 Dimensional Modeling。其中日期
維度必須符合以下規定:
DAX計算時,所涵蓋的日期必須包含在內。日期表必須從1月1日開始,並在12月31日結束,並確保所有天數都存在。
需要有一個包含唯一值的DateTime或Date數據類型的欄位。在我們的例子中 date
就是一個日期維度表,欄位則是 date_day
,簡單說就是日曆。
這個 日期
維度表必須被標示為日期資料表,如下圖所示。
在之前的語意模型中,我們利用 DAX 新增了一個量值 (Measure / Metrics) : Sales Revenue = SUM('orders'[total_amount])
,現在我們再新增兩個量值,分別是:
MTD Sales Amount = CALCULATE( [Sales Revenue], DATESMTD('date'[date_day]))
YTD Sales AMount = CALCULATE( [Sales Revenue], DATESYTD('date'[date_day]))
可以看到 DAX 中使用了之前就已經定義好的量值:[Sales Revenue],DAX 的一個特色就是可以重複利用定義好的指標, 這樣就形成了 Sales Revenue 的 MTD 以及 YTD。接下來為了方便解釋,將 ** Sales Revenue, MTD Sales Revenue 以及 YTD Sales Revenue ** 放到同一張樞紐分析表比較:
以 2021 年 11 月 22 日為例,三個指標分別代表:
可以發現,雖然在樞紐分析表中都是 2021 年 11 月 22 日,但根據 DAX 不同,date
這張表去篩選出 order
中哪些列來進行運算的方式也不同。
另外,很多人解讀 DATESMTD()
, DATESYTD()
喜歡用 截至今日,但我認為, DATESMTD()
, DATESYTD()
的 input 是單一日期,解讀時是將視覺效果 (Visualization,也就是這個例子中的樞紐分析表)的日期傳遞進 DAX 中做解讀,因此應該用**截至該月份當日 (DATESMTD()
) 或是該年度當日 (DATESYTD()
) ** 會比較妥當,或是像上面一樣,直接把日期的值帶入解讀當中。
YoY 其實相當簡單:我們要先計算當年度的量值,在計算前年度的量值,最後組合出 YoY。
有一個函數 sameperiodlastyear()
,只要把他加到 DATESMTD()
或是 DATESYTD()
的外面就可以了。
舉例來說,SAMEPERIODLASTYEAR(DATESMTD('2021-11-22'))
就可以解讀成, 2021 年 11 月 截至 22 日為止 (也就是 2021-11-01 到 2021-11-22) 的去年同期,那就是 2020-11-01 到 2021-11-22啦。這裡可以先定義前一年的加總,再定義 YoY MTD 。
Previous Year MTD Sales Revenue = CALCULATE( [Sales Revenue], SAMEPERIODLASTYEAR(DATESMTD('date[date_day])))
YoY MTD Sales Revenue = DIVIDE([MTD Sales Revenue] - [Previous Year MTD Sales Revenue],[Previous Year MTD Sales], BLANK())