Ssas PY YTD计算的度量,可处理闰年MDX

Ssas PY YTD计算的度量,可处理闰年MDX,ssas,mdx,olap,cube,Ssas,Mdx,Olap,Cube,这可能是一个长期的问题,但这里可能有一位ssas/mdx大师,他在聚合计算和闰年方面遇到了同样的问题。所以我想做的是,在ssas多维数据集中创建一个PY YTD计算的度量,它可以处理闰年。我面临的问题是,基于下面的逻辑,计算出的度量变得非常慢(参见代码示例)。有没有人找到更好的方法来处理闰年,或者有一份最佳实践的文档可以分享?我假设if语句和非空函数对于计算的度量可能是致命的性能。非常感谢所有提示(不一定是解决方案) 致以最良好的祝愿, Rubrix尝试以下操作,下面是一些注意事项: CREAT

这可能是一个长期的问题,但这里可能有一位ssas/mdx大师,他在聚合计算和闰年方面遇到了同样的问题。所以我想做的是,在ssas多维数据集中创建一个PY YTD计算的度量,它可以处理闰年。我面临的问题是,基于下面的逻辑,计算出的度量变得非常慢(参见代码示例)。有没有人找到更好的方法来处理闰年,或者有一份最佳实践的文档可以分享?我假设if语句和非空函数对于计算的度量可能是致命的性能。非常感谢所有提示(不一定是解决方案)

致以最良好的祝愿,
Rubrix

尝试以下操作,下面是一些注意事项:

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谢谢你的回复。闰年和上一年迄今为止的问题是“平行期”不知道日历,因此它不知道2019年2月有28天,而2020年2月有29天(即闰年)。因此,当您将2020-02-29与前一年进行比较时,它将返回空值,因为2019年2月没有成员29。我发布的解决方案很有效,但速度相当慢。所以我想知道是否有人使用了不同的方法。所以我想让它做的是,总是将2月与28日进行比较,所以当有第29个成员时,它应该改为28。那么你将永远不会遇到像2020-02-29和2019-02-29这样返回空值的情况,因为我们都知道2019年没有2019-02-29。Hello@MitchSchroeter我用我的数据测试了你的解决方案,得到了一些与正确结果相比的偏差(较小的值)。所以我猜一天或更多的时间被排除在外。我在一个新的ssas项目中使用AdventureWorks数据库构建了时间计算。但我在尝试使用Excel中的维度时遇到了问题。例如,在选择YTD Cur时,没有显示成员。这是我的代码中的一个错误,我缺少一个分号。到目前为止,该解决方案工作得很好,但尚未对其进行任何重大性能测试。谢谢你@MitchSchroeter
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;