第06篇:DAX 进阶:时间智能与复杂计算
1. 时间智能概述
时间智能(Time Intelligence)是 DAX 中专门用于处理日期和时间的强大功能,让你可以轻松计算同比、环比、年累计、月累计等分析指标。
时间智能的前提:模型中必须有一张日期表(Date Table),且与事实表建立了关系。
2. 建立日期表
日期表是时间智能的基础,必须满足以下条件:
- 包含从起始日期到结束日期的连续日期序列
- 每行对应一天,无遗漏
- 日期列是唯一值(不能有重复日期)
2.1 使用 DAX 自动创建日期表
dax
日期表 =
CALENDAR(
DATE(2020, 1, 1), -- 起始日期
DATE(2025, 12, 31) -- 结束日期
)
这会生成一个包含所有日期的表。
2.2 创建带年/月/季度列的完整日期表
dax
日期表 =
ADDCOLUMNS(
CALENDAR(DATE(2020,1,1), DATE(2025,12,31)),
"年", YEAR([Date]),
"季度", "Q" & QUARTER([Date]),
"月", FORMAT([Date], "yyyy-MM"),
"月份名称", FORMAT([Date], "MMMM"),
"星期", WEEKDAY([Date]),
"年度第几周", WEEKNUM([Date])
)
2.3 标记日期表
建立日期表后,必须将其标记为日期表:
- 在数据视图中,选中日期表
- 点击"表格工具" → "标记为日期表" → 选择日期列
3. 常用时间智能函数
3.1 TOTALYTD / TOTALQTD / TOTALMTD
年累计(Year-to-Date):
dax
销售额_YTD = TOTALYTD(SUM(销售[销售额]), '日期表'[Date])
季度累计(Quarter-to-Date):
dax
销售额_QTD = TOTALQTD(SUM(销售[销售额]), '日期表'[Date])
月累计(Month-to-Date):
dax
销售额_MTD = TOTALMTD(SUM(销售[销售额]), '日期表'[Date])
3.2 SAMEPERIODLASTYEAR(去年同期)
dax
销售额_去年同期 =
CALCULATE(
SUM(销售[销售额]),
SAMEPERIODLASTYEAR('日期表'[Date])
)
3.3 PARALLELPERIOD(平移周期)
将日期平移指定月数或季度:
dax
-- 上年同期(与SAMEPERIODLASTYEAR效果类似)
销售额_上年同期 =
CALCULATE(
SUM(销售[销售额]),
PARALLELPERIOD('日期表'[Date], -1, YEAR)
)
-- 上月同期
销售额_上月同期 =
CALCULATE(
SUM(销售[销售额]),
PARALLELPERIOD('日期表'[Date], -1, MONTH)
)
4. 同比与环比计算
4.1 同比增长率(YoY)
dax
销售额_同比增长率 =
DIVIDE(
[销售额] - [销售额_去年同期],
[销售额_去年同期]
)
4.2 环比增长率(MoM)
dax
-- 先计算上月销售额
销售额_上月 =
CALCULATE(
SUM(销售[销售额]),
PARALLELPERIOD('日期表'[Date], -1, MONTH)
)
-- 环比增长率
销售额_环比增长率 =
DIVIDE(
[销售额] - [销售额_上月],
[销售额_上月]
)
4.3 季度环比
dax
销售额_上季 =
CALCULATE(
SUM(销售[销售额]),
PARALLELPERIOD('日期表'[Date], -1, QUARTER)
)
销售额_季度环比 =
DIVIDE([销售额] - [销售额_上季], [销售额_上季])
5. 移动平均
使用 AVERAGEX 配合 DATESINPERIOD 计算移动平均:
dax
-- 7日移动平均
销售额_7日移动平均 =
AVERAGEX(
DATESINPERIOD('日期表'[Date], LASTDATE('日期表'[Date]), -7, DAY),
CALCULATE(SUM(销售[销售额]))
)
dax
-- 12个月移动平均
销售额_12月移动平均 =
AVERAGEX(
DATESINPERIOD('日期表'[Date], LASTDATE('日期表'[Date]), -12, MONTH),
CALCULATE(SUM(销售[销售额]))
)
6. 复杂计算进阶
6.1 RANKX 排名
dax
-- 按销售额排名(降序)
产品销售排名 =
RANKX(
ALL(产品[产品名称]),
[销售额],
,
DESC,
DENSE
)
参数说明:
ALL(产品[产品名称])定义排名的范围,DESC表示降序,DENSE表示dense排名(无跳号)。
6.2 TOPN 取前N名
dax
销售额前3产品 =
TOPN(
3,
ALL(产品[产品名称]),
[销售额],
DESC
)
6.3 HASONEVALUE 单值判断
dax
-- 仅在选择了单一产品时才显示百分比
产品销售占比 =
IF(
HASONEVALUE(产品[产品名称]),
DIVIDE([销售额], CALCULATE([销售额], ALL(产品))),
BLANK()
)
6.4 使用变量(VAR)优化性能
dax
利润率_同比变化 =
VAR CurrentMargin = [利润率]
VAR LastYearMargin = [利润率_去年同期]
RETURN
DIVIDE(CurrentMargin - LastYearMargin, LastYearMargin)
使用
VAR的好处:
- 避免重复计算同一个表达式,提升性能
- 让复杂的 DAX 公式更易读
- 可以定义多个中间变量
7. 常见分析场景模板
| 分析场景 | 推荐 DAX 公式 |
|---|---|
| 年累计销售额 | TOTALYTD(SUM(销售[销售额]), 日期表[Date]) |
| 去年同期销售额 | CALCULATE(SUM(销售[销售额]), SAMEPERIODLASTYEAR(日期表[Date])) |
| 同比增长率 | DIVIDE([销售额] - [销售额_去年同期], [销售额_去年同期]) |
| 月累计 | TOTALMTD(SUM(销售[销售额]), 日期表[Date]) |
| 季度累计 | TOTALQTD(SUM(销售[销售额]), 日期表[Date]) |
| 移动平均(7日) | AVERAGEX(DATESINPERIOD(...), CALCULATE(SUM(...))) |
| 产品排名 | RANKX(ALL(产品), [销售额]) |
8. 小结
本篇介绍了:
- ✅ 日期表的创建与标记
- ✅ TOTALYTD / TOTALQTD / TOTALMTD 时间累计函数
- ✅ SAMEPERIODLASTYEAR 和 PARALLELPERIOD 同比/环比计算
- ✅ 同比增长率和环比增长率的 DAX 实现
- ✅ 移动平均(AVERAGEX + DATESINPERIOD)
- ✅ RANKX 排名、TOPN 取前N、VAR 变量优化
下一篇:我们将进入可视化环节,学习如何选择合适的图表类型,设计清晰美观的报表,以及 Power BI 可视化的最佳实践。