PY YTD 计算的可以处理闰年 MDX 的度量
Posted
技术标签:
【中文标题】PY YTD 计算的可以处理闰年 MDX 的度量【英文标题】:PY YTD calculated measure that can handle leap years MDX 【发布时间】:2020-03-25 09:33:36 【问题描述】:这可能是一个远景,但也许这里有一位 ssas/mdx 大师偶然发现了关于聚合计算和闰年的相同问题。所以我想做的是在一个可以处理闰年的 ssas 立方体中创建一个 PY YTD 计算度量。我面临的问题是,根据下面的逻辑计算的度量变得非常慢(参见代码示例)。有没有人找到更好的方法来处理闰年或有最佳实践的文档要分享?我假设 if 语句和 NonEmpty 函数对于计算的度量可能是致命的。非常感谢所有提示(不一定是解决方案)。
-- YTD PRIOR YEAR
[Time Calculations].[YTD Pr Yr] = IIF([Calendar].[Year - Month - Day].CurrentMember IS [Calendar].[Year - Month - Day].[Month].&[201702]
,Aggregate(
NonEmptyCrossjoin([Time Calculations].[Current Period],
PeriodsToDate(
[Calendar].[Year - Month - Day].[Year],
[Calendar].[Year - Month - Day].[Day].&[2016-02-29 00:00:00.000])
))
,IIF([Calendar].[Year - Month - Day].CurrentMember IS [Calendar].[Year - Month - Day].[Month].&[201602]
,Aggregate(
NonEmptyCrossjoin([Time Calculations].[Current Period],
PeriodsToDate(
[Calendar].[Year - Month - Day].[Year],
[Calendar].[Year - Month - Day].[Day].&[2015-02-28 00:00:00.000])
))
,(Aggregate(
NonEmptyCrossjoin([Time Calculations].[Current Period],
PeriodsToDate(
[Calendar].[Year - Month - Day].[Year],
ParallelPeriod(
[Calendar].[Year - Month - Day].[Year],1,
TAIL(DESCENDANTS([Calendar].[Year - Month - Day].CurrentMember
, [Calendar].[Year - Month - Day].[Day]),1).ITEM(0)))
)
)
)
)
);
最好的问候, 红宝石
【问题讨论】:
当你说“问题”时,究竟是什么意思?你期望它的表现如何?我可以为您提供一个可以有效解决问题的解决方案,但它可能无法满足您的特定业务需求。 嘿@MitchSchroeter 谢谢你的回复。闰年和上一年年初至今的问题是“平行期”不知道日历,所以它不知道 2019 年 2 月有 28 天,而 2020 年 2 月有 29 天(即闰年)。因此,当您将 2020-02-29 与上一年进行比较时,它将返回 null,因为 2019 年 2 月没有成员 29。我发布的解决方案有效,但速度相当慢。所以我想知道是否有人使用了不同的方法。 所以我想要它做的就是总是将二月与 28 进行比较,所以当有第 29 个成员时,它应该更改为 28。那么你将永远不会遇到像 2020-02- 这样的情况29 与 2019-02-29 返回 NULL,因为我们都知道 2019 年没有 2019-02-29。 【参考方案1】:尝试以下方法,以下是一些注意事项:
CREATE MEMBER CURRENTCUBE.[Time Calculations].[YTD Prior Year] AS NULL;
/* Make sure the scope is for all days in all years in your calendar year */
Scope([Invoice Date].[Calendar Year].[Calendar Year].members, [Invoice Date].[Calendar Day].members);
// YTD PRIOR YEAR
([Time Calculations].[YTD Prior Year] =
iif(
/* Check to see if the prior year member is empty */
isempty(
ParallelPeriod(
[Invoice Date].[CY Hierarchy].[Calendar Year],
1,
[Invoice Date].[CY Hierarchy].CurrentMember
).MemberValue
),
/* If so, use the .LastChild */
Aggregate(
Crossjoin(
[Time Calculations].[Current Period],
PeriodsToDate(
[Invoice Date].[CY Hierarchy].[Calendar Year],
ParallelPeriod(
[Invoice Date].[CY Hierarchy].[Calendar Year],
1,
Ancestor(
[Invoice Date].[CY Hierarchy].CurrentMember,
[Invoice Date].[CY Hierarchy].[Calendar Month]
)
).LastChild
)
)
),
/* Otherwise just use the prior year */
Aggregate(
Crossjoin(
[Time Calculations].[Current Period],
PeriodsToDate(
[Invoice Date].[CY Hierarchy].[Calendar Year],
ParallelPeriod(
[Invoice Date].[CY Hierarchy].[Calendar Year],
1,
[Invoice Date].[CY Hierarchy].CurrentMember
)
)
)
)
)
);
End Scope;
一个可能的问题是,如果您连续几天没有交易,.LastChild 可能无法正常工作。我最初开发此代码时没有这种情况。它是专门为处理以前年初至今和闰年细微差别的确切情况而开发的。如果是这种情况,可能需要对其进行调整。
这假设您有一个适当的时间维度和一个时间计算维度,看起来就像您从您提供的代码示例中所做的那样。
我想说,即使在大型立方体(数亿行)上,此解决方案的性能也非常出色。
【讨论】:
您好@MitchSchroeter 我确实用我的数据测试了您的解决方案,并且与正确结果相比出现了一些偏差(价值较小)。所以我猜一/多天被排除在外。我已经使用冒险作品数据库在一个新的 ssas 项目中建立了时间计算。但是我在尝试在 Excel 中使用维度时遇到了问题。选择YTD Cur例如时,不会显示该构件。 span> 这是我的代码中的一个错误,我缺少一个分号。到目前为止,该解决方案效果很好,但还没有真正对其进行任何繁重的性能测试。谢谢@MitchSchroeter以上是关于PY YTD 计算的可以处理闰年 MDX 的度量的主要内容,如果未能解决你的问题,请参考以下文章
查询 (2, 2) 默认情况下,需要一个年份级别。在 MDX 查询不起作用的 cube.ytd 函数中没有找到这样的级别