PY YTD 可处理闰年 MDX 的计算量度
PY YTD calculated measure that can handle leap years MDX
这可能是一个远景,但也许这里有一位 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)))
)
)
)
)
);
此致,
规则
尝试以下操作,注意事项如下:
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 可能无法正常工作。我最初开发这段代码时没有那种情况。它是专门为处理上一年至今和闰年细微差别的这种确切情况而开发的。如果是这种情况,可能需要对其进行调整。
这假设您有一个适当的时间维度和一个时间计算维度,从您提供的代码示例中看起来就像您所做的那样。
我想说这个解决方案的性能即使在大型多维数据集(数亿行)上也非常好。
这可能是一个远景,但也许这里有一位 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)))
)
)
)
)
);
此致, 规则
尝试以下操作,注意事项如下:
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 可能无法正常工作。我最初开发这段代码时没有那种情况。它是专门为处理上一年至今和闰年细微差别的这种确切情况而开发的。如果是这种情况,可能需要对其进行调整。
这假设您有一个适当的时间维度和一个时间计算维度,从您提供的代码示例中看起来就像您所做的那样。
我想说这个解决方案的性能即使在大型多维数据集(数亿行)上也非常好。