跟大家的交流是我的動力。 :)

Update 2019/Jul/11:增加如何生成時間維度表(時刻分鍾)文章鏈接
Update 2017/Oct/06:更新了生成日期為度的腳本- #"Changed Type"
Update 2017/Sep/21 :來信的一些童鞋都用事實表(Fact Table)來作為時間維度的計算,對於簡單的計算並沒有問題,但是對於復雜的涉及到更多的FilterContext的transition的時候,這樣的設計往往就不能實現,所以強烈建議單獨建一個時間維度表(Date Dimension)---- 這個涉及到一些些data warehousing的一些基礎知識。
還等什么,往下瞅瞅!!
DAX/PowerBI系列 - 關於時間系列 - 如何用腳本生成時間維度 (Generate Date Dimension)
難度: ★☆☆☆☆(1星)
適用范圍: ★★★★★(5星)
這個時間系列想寫很久了,今天開始走一小步。也是作為后續關於時間計算文章的基礎。 (文末發一個小福利。 )
概況:
關於時間序列的計算是一個很(也)常(很)用(大)的topic,而且應用范圍很廣,譬如計算同比,環比,根據時間序列預測某個值。必不可少的就是在模型里面有一個日期的維度。
PowerBI提供了一個AutoCalendar的函數來生成一個日期的時間表,很好!但它僅此生成一個日期列。
可素,往往我們需要很多其他的日期屬性列,譬如:單獨的年,月,日,季度,財年,等等。我們可以添加計算列,把它們一個一個加進來,但是我另外一個model也需要這個時間維度表呢?
重復添加計算列,這個活真的比較無趣。有沒有什么好方法去避免吶?
這個就是今天的主題:如何用腳本生成時間維度。(How to use script to generate date dimension)
如何生成時刻分鍾維度的文章,請戳這里。
應用場景:
以下是幾個應用場景:
- 復用時間維度表
- 偷懶不想一個個添加時間屬性列
- 分析時間序列
- 分析同比環比等需要一個日期維度
最終PowerBI效果顯示如下:

要點:
按下面步驟操作,具體M語言是什么,可以忽略。(下面的屬性不夠用再參考M語言是什么)
1.PowerBI面板>Edit Query進入Qery Editor> New Source > Blank Query>

2. Advanced Edictor,貼入文末腳本並保存。

3.填入參數,點[Invoke]

4.哇啦,你得到一個時間維度表啦,(*^__^*) 嘻嘻……

腳本如下:(拿走,不謝)
腳本使用M語言寫的,如果想修改添加其他的列,參考一下M語言。 (又一種語言,╮(╯▽╰)╭)
1 (StartDate as date, YearsToAppend as number, FinancialYearStartingMonth as number ) => 2 let 3 4 YearsToAppend = YearsToAppend, 5 FinancialYearStartingMonth= FinancialYearStartingMonth, 6 StartDate = #date(Date.Year(StartDate), Date.Month(StartDate), Date.Day(StartDate)), 7 // Generate base table 8 Source = List.Dates(Date.From(StartDate),YearsToAppend*365,#duration(1, 0, 0, 0)), 9 Transformed = List.Transform(Source, each Date.ToRecord(_)), 10 Tabled = Table.FromList(Transformed,Record.FieldValues,{"Year","Month","Day"}), 11 //Add Full Date Column 12 AddDateKey = Table.AddColumn(Tabled,"Date",each Date.FromText(Text.From([Year])&"-"&Text.From([Month])&"-"&Text.From([Day]))), 13 //DateBKeyConvert = Table.TransformColumnTypes(Date,{{"Date", type date}}), 14 DateKeyAdded = Table.AddColumn(AddDateKey,"DateKey",each ([Year] * 10000) + ([Month] * 100) + [Day]), 15 FullDateNameAdded = Table.AddColumn(DateKeyAdded,"DateFullName",each DateTime.ToText(DateTime.From([Date]),"dd MMMM yyyy")), 16 // Calendar Quarter 季度 17 CalendarQuarterAdded = Table.AddColumn(FullDateNameAdded, "Calendar Quarter", 18 each Number.IntegerDivide(Date.Month([Date])-1,3) + 1 19 ), 20 // Calendar Month Number 年月 21 CalendarMonthNumberAdded = Table.AddColumn(CalendarQuarterAdded, "Calendar Month Number", 22 each Date.Year([Date]) * 100 + Date.Month([Date]) 23 ), 24 // Is Week Day 工作日 or 周末 25 WeekDayAdded = Table.AddColumn(CalendarMonthNumberAdded, "IsWeekDay", 26 each 27 if 28 Date.DayOfWeek(DateTime.From([Date]))=Day.Sunday 29 or 30 Date.DayOfWeek(DateTime.From([Date]))=Day.Saturday 31 then 0 else 1 ), 32 // Day Of Week 33 DayOfWeek = Table.AddColumn(WeekDayAdded,"DayOfWeek",each Date.DayOfWeek(DateTime.From([Date]))), 34 // Month Name 35 MonthName = Table.AddColumn(DayOfWeek,"Month Name",each DateTime.ToText(DateTime.From([Date]),"MMMM")), 36 // Day of Week Name 37 DayOfWeekName = Table.AddColumn(MonthName,"Day of Week Name",each DateTime.ToText(DateTime.From([Date]),"dddd")), 38 39 // Fiscal Year 財年 40 FiscalYearAdded = Table.AddColumn(DayOfWeekName, 41 "Fiscal Year", 42 each 43 if Date.Month([Date]) >= FinancialYearStartingMonth then 44 Date.Year([Date]) + 1 45 else 46 Date.Year([Date]) 47 ), 48 // Fiscal Month 財年月份 49 FiscalQuarterAdded = Table.AddColumn(FiscalYearAdded, 50 "Fiscal Quarter", 51 each 52 if Date.Month([Date])>=FinancialYearStartingMonth then 53 Number.IntegerDivide((Date.Month([Date])-FinancialYearStartingMonth),3) + 1 54 else 55 Number.IntegerDivide((12 + Date.Month([Date])-FinancialYearStartingMonth),3) + 1 56 ), 57 58 #"Changed Type" = Table.TransformColumnTypes(FiscalQuarterAdded,{{"DateFullName", type text}, {"DateKey", Int64.Type}, {"Calendar Quarter", Int64.Type}, {"Calendar Month Number", Int64.Type}, {"IsWeekDay", type logical}, {"DayOfWeek", Int64.Type}, {"Month Name", type text}, {"Day of Week Name", type text}, {"Fiscal Year", Int64.Type}, {"Fiscal Quarter", Int64.Type}, {"Day", Int64.Type}, {"Month", Int64.Type}, {"Year", Int64.Type}, {"Date", Date.Type}}) 59 in 60 #"Changed Type"
