Попробуйте следующее, некоторые предостережения следуют:
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 может работать некорректно. У меня не было той ситуации, когда я изначально разрабатывал этот код. Он был специально разработан для того, чтобы разобраться с этим конкретным случаем прошлых нюансов и нюансов високосного года. В этом случае, возможно, потребуется настроить его.
Это предполагает, что у вас есть правильное измерение времени и измерение вычислений времени, что похоже на то, что вы делаете из предоставленного вами примера кода.
Я бы сказал, что производительность этого решения довольно велика даже на больших кубах (сотни миллионов строк).