在 Power BI 中,日期表是数据模型中不可或缺的一部分。它为时间智能功能(如同比、环比、日期差异等)提供了基础支持,也是执行时间维度分析时最常用的工具之一。但问题来了:如何在 Power BI 中创建一个适合自己需求的日期表?
今天,我们就来探讨一下 Power BI 中创建日期表的各种方式。无论你是新手还是有经验的 Power BI 使用者,都会从中受益,掌握几种常见而实用的创建日期表的方法。
使用 DAX 创建日期表
DAX 提供了强大的日期函数,使得创建灵活的日期表变得容易。
基本日期表
你可以通过以下的 DAX 公式创建一个包含指定时间范围的基础日期表:
DateTable =
CALENDAR( DATE( 2020 , 1 , 1 ) , DATE( 2025 , 12 , 31 ) )
这个公式创建了一个从 2020 年 1 月 1 日到 2025 年 12 月 31 日的日期表。如果你想要生成不同时间范围的日期表,只需要调整 CALENDAR
函数中的日期参数即可。或者使用 CALENDARAUTO
函数,它会根据数据模型中事实表的日期范围自动创建日期表。
添加时间维度
除了日期列,通常还需要添加其他的时间维度,如年份、季度、月份、星期等。可以通过 YEAR()
、MONTH()
等 DAX 函数来实现:
DateTable =
ADDCOLUMNS (
CALENDAR ( DATE ( 2020, 1, 1 ), DATE ( 2025, 12, 31 ) ),
"Year", YEAR ( [Date] ),
"Quarter", QUARTER ( [Date] ),
"Month", MONTH ( [Date] ),
"Day", DAY ( [Date] ),
"Weekday", WEEKDAY ( [Date], 2 ) // 2表示周一为一周的第一天
)
这样,你就得到了一个包含完整时间维度的日期表,能够支持多种时间相关分析。
如果对日期表的时间维度字段有语言要求,可以使用以下 FOTMAT 函数 + 区域设置实现,如下。
如果我们把区域设置“en-us”改为“de-DE”,会发生什么呢?
MonthName 和 Weekday 列的值从英文变成了德文,如果我们改成“zh-CN”,会显示中文吗?
很遗憾,不可以。
这里的原因我们之前介绍过,感兴趣的小伙伴可以看:神操作!DAX 生成中文日期表
以下是解决办法。
日期表 =
ADDCOLUMNS (
CALENDAR ( "2019/1/1" , "2022/12/31" ) ,
"年序号" , YEAR ( [Date] ),
"年份名称", YEAR ( [Date] ) & "年" ,
"季度", QUARTER ( [Date] ) ,
"季度名称" , "Q" & QUARTER ( [Date] ) ,
"月份序号" , MONTH ( [Date] ) ,
"月份名称" , FORMAT ( [Date] , "OOOO" ),
"月份简称" , FORMAT ( [Date] , "OOO" ),
"星期几" , FORMAT ( [Date] , "AAAA" ),
"周几" , FORMAT ( [Date] , "AAA" )
)
效果。
使用 DAX 创建日期表要先创建出一个日期列,然后在日期列的基础上添加各种我们需要的维度即可。
使用 Power Query 创建日期表
另一种创建日期表的方法是通过 Power Query(查询编辑器)。在 Power Query 中,可以通过自定义列和步骤来构建日期表。与 DAX 不同,Power Query 更加灵活。
如果你的 Power Query 中存在日期列,那你生成日期表只需要点点点,因为 Power Query 提供了生成不同时间维度字段的可视化方法。
具体方法参考:PowerQuery 技巧:可视化操作生成日期表
除了这种方法,我们还可以使用 Power Query 中的 M 函数 DateTime.ToText 实现。只需要一个函数,搞定全部日期维度字段,还可以进行区域设置。
进行分割之后的效果。
具体参考:PowerQuery 日期表进阶:自定义日期字段格式
如果你的数据是动态的,日期范围会不断变化(例如,数据可能会每天更新),还可以通过创建一个动态的日期表来自动适应新的时间范围。具体 M 语句如下。
List.Dates(
Date.StartOfMonth(List.Min(#"Fact 订单"[#"订单日期"])),
Duration.Days(
Date.EndOfMonth(List.Max(#"Fact 订单"[#"订单日期"]))
- Date.StartOfMonth(List.Min(#"Fact 订单"[#"订单日期"]))
)
+ 1,
#duration(1, 0, 0, 0)
)
然后在此基础上重复进行第一种或者第二种操作即可,这样就能到一个跟随事实表时间范围变化而变化的日期表。
财年表
除了基础的日期表,日期用到的日期表还有财年日期表或运营日期表,这些复杂的日期表又怎么实现呢?
这里给到大家两种解决办法,一种是在 Power Query 里面实现,一种是使用 DAX 实现。
Power Query
Power Query 实现财年表分为多个步骤,这里直接给出完整代码,大家创建完参数之后,直接复制粘贴即可。
let
源 = List.Dates(StartDate, Duration.Days(EndDate - StartDate) + 1, #duration(1, 0, 0, 0)),
转换为表 = Table.FromList(源, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
重命名的列 = Table.RenameColumns(转换为表, {{"Column1", "Date"}}),
更改的类型 = Table.TransformColumnTypes(重命名的列, {{"Date", type date}}),
已添加财年开始日期 = Table.AddColumn(
更改的类型,
"财年开始日期",
each
if Date.Month([Date]) < #"FY StartMonth" then
#date(Date.Year([Date]) - 1, #"FY StartMonth", 1)
else
#date(Date.Year([Date]), #"FY StartMonth", 1)
),
已添加财年 = Table.AddColumn(已添加财年开始日期, "财年", each Date.Year([财年开始日期]) + 1),
已添加财年月份 = Table.AddColumn(
已添加财年,
"财年月份",
each
if Date.Month([Date]) >= #"FY StartMonth" then
Date.Month([Date]) - #"FY StartMonth" + 1
else
Date.Month([Date]) - #"FY StartMonth" + 1 + 12
),
已添加财年周序号 = Table.AddColumn(
已添加财年月份,
"财年周序号",
each Number.IntegerDivide(Duration.Days([Date] - Date.StartOfWeek([财年开始日期], Day.Monday)), 7) + 1
),
已添加周几 = Table.AddColumn(已添加财年周序号, "周几", each Date.DayOfWeekName([Date], "zh-CN")),
已添加年周序号 = Table.AddColumn(已添加周几, "年周序号", each [财年] * 100 + [财年周序号]),
已添加季度 = Table.AddColumn(
已添加年周序号,
"财年季度",
each Text.Combine({"Q", Number.ToText(Number.IntegerDivide([财年月份] - 1, 3) + 1)})
),
更改的类型1 = Table.TransformColumnTypes(
已添加季度,
{
{"Date", type date},
{"财年开始日期", type date},
{"财年", Int64.Type},
{"财年月份", Int64.Type},
{"财年周序号", Int64.Type},
{"周几", type text},
{"年周序号", Int64.Type},
{"财年季度", type text}
}
)
in
更改的类型1
想要详细了解整个过程的小伙伴参考:用 PowerQuery 快速构建一个财年日期表
DAX
如果你需要一个更牛的财年运营表,看下面这张图,支持财年设置、运营月和运营周设置。
完整 DAX 语句如下。
Model.DatesTemplate =
VAR BeginDate = MINX( {
MIN( '订单'[订单日期] ) , // 【配置】根据实际修改
MIN( '订单'[发货日期] ) // 【配置】根据实际修改
} , [Value] )
VAR EndDate = MAXX( {
MAX( '订单'[订单日期] ) , // 【配置】根据实际修改
MAX( '订单'[发货日期] ) // 【配置】根据实际修改
} , [Value] )
VAR vFiscalDate = "1231" // 文本"1231" 设置 "0630" 表示 6月30日
VAR vOperateEndDayInMonth = 31 // 数字31 设置 1 ... 31
VAR vOperateEndDayInWeek = 7 // 数字7 设置 1 ... 7
VAR vDateLine =
CALENDAR(
DATE( YEAR( BeginDate ) - IF( vFiscalDate <>"1231" , 1 ) , 1 , 1 ) ,
DATE( YEAR( EndDate ) + IF( vFiscalDate <>"1231" , 1 ) , 12 , 31 )
)
VAR vBeginDate = MINX( vDateLine , [Date] )
VAR vCalendar =
ADDCOLUMNS(
vDateLine ,
"索引" , VALUE( [Date] - vBeginDate ) ,
"全局周序号" , INT( ( VALUE( [Date] - vBeginDate ) + 7 - WEEKDAY( [Date] , 2 ) ) / 7 ) ,
"年序号" , YEAR( [Date] ) ,
"年名称" , "Y" & YEAR( [Date] ) ,
"季序号" , VALUE( FORMAT( [Date] , "Q" ) ) ,
"季名称" , "Q" & FORMAT( [Date] , "Q" ) ,
"年季序号" , YEAR( [Date] ) * 10 + QUARTER( [Date] ) ,
"月序号" , MONTH( [Date] ) ,
"月名称(英文)" , FORMAT( [Date] , "mmm" ),
"月名称" , MONTH( [Date] ) & "月",
"年月序号" , YEAR( [Date] ) * 100 + MONTH( [Date] ) ,
"周序号" , WEEKNUM( [Date] , 2 ) ,
"年周序号" , YEAR( [Date] ) * 100 + WEEKNUM( [Date] , 2 ) ,
"月第几日" , DAY( [Date] ) ,
"周第几日" , WEEKDAY( [Date] , 2 ),
"星期几" , RIGHT( FORMAT( [Date] , "aaa" ) , 1 ),
"年第几日" , VALUE( FORMAT( [Date] , "y" ) )
)
VAR vFiscalMonth = IF( LEN( vFiscalDate ) = 4 , VALUE( LEFT( vFiscalDate , 2 ) ) , ERROR( "财务日期必须是4位文本,如:0630表示6月30日" ) )
VAR vFiscalDay = VALUE( RIGHT( vFiscalDate , 2 ) )
VAR vCalendarExtend =
ADDCOLUMNS( vCalendar ,
"财务年序号" ,
VAR vFiscalEndDatePY = DATE( [年序号], vFiscalMonth , vFiscalDay )
RETURN IF( [Date] > vFiscalEndDatePY , [年序号] + 1 , [年序号] ) ,
"运营年月序号" ,
IF( [月第几日] > vOperateEndDayInMonth , YEAR( EOMONTH( [Date] , 1 ) ) * 100 + MONTH( EOMONTH( [Date] , 1 ) ) , [年月序号] )
,
"运营周序号" ,
IF( [周第几日] > vOperateEndDayInWeek , [全局周序号] + 1 , [全局周序号] )
)
VAR vCalendarExtend2 =
ADDCOLUMNS( vCalendarExtend ,
"财务年名称" , "FY" & RIGHT( [财务年序号] - 1 , 2 ) & RIGHT( [财务年序号] , 2 ),
"上个财务年序号" , [财务年序号] - 1 ,
"上个运营年月序号" , IF( MOD( [运营年月序号] , 10 ) > 1 , [运营年月序号] - 1 , ( VALUE( LEFT( [运营年月序号] & "" , 4 ) ) - 1 ) * 100 + 12 ) ,
"上个运营周序号" , [运营周序号] - 1
)
RETURN vCalendarExtend2
关于以上 DAX 日期表的更多信息,参考:【DAX 系列】PowerBI 日期表模型 - 支持财年与运营月运营周
总结
在 Power BI 中创建日期表是一项基础且重要的任务,它是进行时间维度分析的基础,无论是通过 DAX 还是 Power Query 都可以实现。对于特定业务需求,像财年表等复杂的日期表,也可以通过 Power Query 和 DAX 来实现。在本文中,我们已经介绍了这两种方法的具体实现步骤,相信你可以根据自身需求选择最合适的方式。
一更专业的数据分析师训练营一
📈【高级课程】:业务人(管理、销售、财务、供应链)彻底解决企业数据分析。
🔍【企业咨询】:十大行业,十大领域,企业案例,咨询,培训,实施。
🔗 如何获取更多信息?扫描下方二维码具体咨询。
点击“阅读原文”获取更多资源