温馨提示:本文翻译自stackoverflow.com,查看原文请点击:ssas - PY YTD calculated measure that can handle leap years MDX
cube mdx olap ssas

ssas - 可以处理leap年MDX的PY YTD计算得出的度量

发布于 2020-06-08 13:38:56

这可能是一个远景,但是这里可能有一个ssas / mdx专家遇到了关于汇总计算和leap年的相同问题。因此,我想做的是在可处理leap年的ssas多维数据集中创建PY YTD计算得出的度量。我面临的问题是,根据以下逻辑,计算得出的度量变得非常慢(请参见代码示例)。有没有人找到处理leap年的更好方法,或者可以共享最佳实践的文档?我假设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)))

    )
    )
    )
    )
);

最好的问候,Rubrix

查看更多

提问者
Rubrix
被浏览
5
Mitch Schroeter 2020-04-16 00:51

请尝试以下操作,一些注意事项如下:

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可能无法正常工作。我最初开发此代码时没有这种情况。它是专门为处理以前的年初至今和leap年细微差别的确切情况而开发的。如果是这种情况,可能需要进行调整。

假定您具有正确的时间维度和时间计算维度,就像您从提供的代码示例中所做的那样。

我要说的是,即使在大型多维数据集(亿万行)上,此解决方案的性能也非常好。