12.6 计算移动总计(Running Total)


## 什么是移动总计 移动总计又称滚动总计,英文 Running Total 或 Moving Total,是计算累计的一种特殊方式,与YTD最大的不同在于,移动总计始终按固定的时间长度回溯,这种处理方式可以消除时间性的周期变化对数据的影响。12.6 计算移动总计(Running Total) - 图1黄色的移动平均数据抵消了周期性波动## 移动年度总计 移动年度总计 (Moving Annual Total 简称 MAT)是一种常见的用于消除销售季节性变化的计算方式,它总是考虑过去 12 个月的数据。例如,你可以通过计算 2007 年 4 月至 2008 年 3 月期间的日期范围来计算 2008 年 3 月的 MAT 销售数据。最简单的方法是使用DATESINPERIOD函数,### DATESINPERIOD DATESINPERIOD ( , , , )| 参数 | 属性 | 描述 | | —- | —- | —- | | Dates |
| 包含日期的列引用 | | StartDate |
| 开始日期 | | NumberOfIntervals |
| 间隔数量,负数代表过去,正数代表将来 | | Interval |
| 间隔类型:年、季度、月或日 |

返回给定区间中的所有日期组成的单列形式的表,该函数应用偏移量(第三参数)到第一参数使用的日期列,返回第四参数所指定区间中包含的所有日期。

  1. [MAT Sales] :=
  2. CALCULATE (
  3. [Sales Amount],
  4. DATESINPERIOD (
  5. ‘Date’[Date],
  6. LASTDATE ( ‘Date’[Date] ),
  7. -1,
  8. YEAR
  9. )
  10. ) 使用DATESINPERIOD通常是计算移动年度总计的最佳选择。出于教学演示目的,了解其他可以构造相同筛选器的方法也很有用。我们考虑下面这个备选的 MAT Sales 定义,它计算每年的移动年度销售总额。
  11. [MAT Sales] :=
  12. CALCULATE (
  13. [Sales Amount],
  14. DATESBETWEEN (
  15. ‘Date’[Date],
  16. NEXTDAY (
  17. SAMEPERIODLASTYEAR (
  18. LASTDATE ( ‘Date’[Date] )
  19. )
  20. ),
  21. LASTDATE ( ‘Date’[Date] )
  22. )
  23. ) 使用这个度量值需要注意:DATESBETWEEN 函数从列中返回包含在两个指定日期之间的日期列表。因为这种计算总是在日级别上发生,即使是在月级别上查询数据,也必须计算所需间隔的第一天和最后一天。你可以通过调用 LASTDATE 函数获得最后一天,该函数返回给定列的最后日期(始终考虑当前筛选上下文)。从这个日期开始,你可以通过请求一年前相应的那个最后日期的第二天(通过调用 NEXTDAY)来获得间隔的第一天。(通过 SAMEPERIODLASTYEAR 实现)在图 7-21 中,你可以看到包含移动年度总计的报告。例如, Q1-2008 对应的 MAT 销售额是将 2007 年第二季度、2007 年第三季度、2007 年第四季度和 2008 年第一季度的销售额相加后得到的结果。在中间,你看到的是经典的年度至今计算公式(YTD),它的值与每年最后一个区间(在本例中是 Q4)的移动年度总计相同。12.6 计算移动总计(Running Total) - 图2图 7-21 此报表使用的度量值仅显示有余额数据的天数## 嵌套函数的调用顺序问题 当你调用嵌套的时间智能函数的时候,你可能想知道正确的调用顺序是什么。在前面的例子中,我们使用下面的 DAX 表达式来检索“移动的年度总计”周期的第一天:
  • NEXTDAY ( SAMEPERIODLASTYEAR ( LASTDATE ( ‘Date’[Date] ) ) ) 在这种情况下,LASTDATE 返回 2008 年第一季度的最后一个日期(2008 年 3 月 31 日),SAMEPERIODLASTYEAR 返回 2007 年 3 月 31 日,NEXTDAY 返回 2007 年 4 月 1 日。你也可以颠倒 NEXTDAY 和 SAMEPERIODLTYYR 之间的调用顺序:
  • SAMEPERIODLASTYEAR ( NEXTDAY ( LASTDATE ( ‘Date’[Date] ) ) ) 它返回相同的结果(2007 年 4 月 1 日),但有一个风险。如果日期表在 2011 年 12 月 31 日结束,并且你考虑的是 2011 年第四季度的结果,那么就会发生这样的情况:LASTDATE 返回 2011 年第四季度的最后一个日期(2011 年 12 月 31 日),NEXTDAY 返回 2012 年 1 月 1 日,SAMEPERIODLASTYEAR 应该返回 2011 年 1 月 1 日。但是,所有这些函数只能返回 Date[Date]列的现有值。如果日期表没有 2012 年的数据,则 NEXTDAY 调用无法返回 2012 年 1 月 1 日,它将改为返回空。例如,考虑以下错误的 MAT 计算:
  1. MAT Sales Wrong :=
  2. CALCULATE (
  3. [Sales Amount],
  4. DATESBETWEEN (
  5. ‘Date’[Date],
  6. SAMEPERIODLASTYEAR (
  7. NEXTDAY (
  8. LASTDATE ( ‘Date’[Date] )
  9. )
  10. ),
  11. LASTDATE ( ‘Date’[Date] )
  12. )
  13. ) 如图 7-22 所示, 2011 年第四季度和 2011 年年度的计值结果都是错误的,尽管 2010 年和 2011 年都没有销售。发生这种情况是因为 DATESBETWEEN 的下边界为空,这将创建一个覆盖整个日期范围的计算。12.6 计算移动总计(Running Total) - 图3图 7-22 MAT Sales Wrong 在 2011 年第四季度和 2011 年全年计值了错误结果