MDX Cookbook 10 - 计算 Year To Date 的 Running Total(YTD 与 PeriodsToDate 的区别)

在这个小节中咱们将计算度量值的 Year To Date 的值,也就是计算从年开始到当前时间成员为止的度量值的累加结果。html

下面的这个查询显示了全部以周为单位的 Reseller Sales Amount -web

那么若是要计算上图中以周为单位的累加值,应该如何处理? 好比说如今是 Week 28 CY 2005,那么它的 YTD 累加值就是 Week 27 CY 2005 的度量值 + Week 28 CY 2005 度量值。函数

WITH MEMBER [Measures].[Reseller Sales YTD] AS SUM( YTD([Date].[Calendar Weeks].CurrentMember), [Measures].[Reseller Sales Amount] ) SELECT { [Measures].[Reseller Sales Amount], [Measures].[Reseller Sales YTD] } ON 0, {[Date].[Calendar Weeks].[Calendar Week].MEMBERS} ON 1 FROM [Adventure Works]

这样就实现了这种累加值的计算,也叫 Running Total。spa

 

YTD() 函数返回是一个集合,是一个时间段的集合。它的起点是当前成员所在层次结构上的第一个时间成员,结束点就是这个当前成员自身。因此对于 Week 28 CY 2005 来讲,它的 YTD 就是 Week 27 CY 2005 到 Week 28 CY 2005;对于 Week 35 CY 2005 来讲,它的 YTD 仍是从 Week 27 CY 2005 到它自身。设计

所以,若是看看 CY 2006 就会发现,YTD() 函数的确是以年做为一个时间参照开始的。而且要注意, CY 2005 的第一个 Week 成员就是 Week 27,可是在 CY 2006 的时候 Week 1 是在 Week 级别中的第一个成员。3d

还有另一种比较简单的方式计算累加,可是要注意这里的累加再也不基于年,而是从当前层次结构上的第一个成员开始到当前成员的这段时间。orm

WITH MEMBER [Measures].[Reseller Sales YTD] AS Sum( (NULL: [Date].[Calendar Weeks].CurrentMember), [Measures].[Reseller Sales Amount] ) SELECT { [Measures].[Reseller Sales Amount], [Measures].[Reseller Sales YTD] }ON 0, {[Date].[Calendar Weeks].[Calendar Week].MEMBERS} ON 1 FROM [Adventure Works]

可是有要注意的地方,若是这里咱们使用的是 Fiscal Week 而不是 Calendar 会出现什么问题?htm

WITH MEMBER [Measures].[Reseller Sales YTD] AS SUM( YTD([Date].[Fiscal Weeks].CurrentMember), [Measures].[Reseller Sales Amount] ) SELECT { [Measures].[Reseller Sales Amount], [Measures].[Reseller Sales YTD] } ON 0, {[Date].[Fiscal Weeks].[Fiscal Week].MEMBERS} ON 1 FROM [Adventure Works]

能够看到的结果是 YTD 的计算所有都不正确。blog

错误信息:By default, a year level was expected. No such level was found.ci

 

缘由是为何呢? [Date].[Calendar Weeks] 这个用户自定义的层次结构有一个级别是 Calendar Year,它的类型是 Years。相对于 [Date].[Calendar Weeks] 的 Fiscal 层次结构是 [Date].[Fiscal Weeks],它有一个级别是 Fiscal Year,它的类型是 FiscalYear 而不是 Years。

YTD() 其实是 PeriodsToDate() 函数的缩写,可是它只能适用于含有 Year 这个类型级别的属性层次结构。若是咱们在开发过程当中忘记这样设计的话,那么咱们就只可使用 PeriodsToDate() 这种原型函数来实现 Year To Date 了。

WITH MEMBER [Measures].[Reseller Sales YTD] AS SUM( PeriodsToDate( [Date].[Fiscal Weeks].[Fiscal Year], [Date].[Fiscal Weeks].CurrentMember ), [Measures].[Reseller Sales Amount] ) SELECT { [Measures].[Reseller Sales Amount], [Measures].[Reseller Sales YTD] } ON 0, {[Date].[Fiscal Weeks].[Fiscal Week].MEMBERS} ON 1 FROM [Adventure Works]

查询结果同样是这样的 Running Total 结果-

 

关于 PeriodsToDate() 函数的使用,个人这篇 MDX 读书笔记中有详细的解释 - MDX Step by Step 读书笔记(九) - Working with Time 处理时间

更多 BI WORK 博客系列看参看 - BI 系列随笔列表 (SSIS, SSRS, SSAS, MDX, SQL Server)

相关文章
相关标签/搜索