I have a cumulative sum of a measure structured as:
Aggregate (
{ NULL : [Date].[Year - Month - Date].CurrentMember }
,[Measures].[Applications] )
From the date of the first application to the current date, the days of the date range must be contiguous.
The Date dimension however contains dates ranging from 1900-01-01 to well into the future.
I've attempted to eliminate dates before the first application, and future dates by structuring the calculated measure as follows:
CREATE MEMBER CURRENTCUBE.[Measures].[Applications TD] AS
CASE
WHEN
/* Eliminates dates before first applications, i.e. year 1900-01-01 */
Aggregate (
{ NULL : [Date].[Year - Month - Date].CurrentMember }
,[Measures].[Applications] ) < 0
THEN NULL
WHEN
/* Eliminates dates after today */
[Date].[Year - Month - Date].CurrentMember.MemberValue >= StrToMember('[Date].[Date].&['+Format(Now(),"yyyy-MM-ddT00:00:00")+']').MemberValue
THEN NULL
ELSE
Aggregate (
{ NULL : [Date].[Year - Month - Date].CurrentMember }
,[Measures].[Applications] )
END
I have been unsuccessful in any attempt to optimizing this by aggregating only where needed using a SCOPE as an alternative to the case statement, utilizing EXISTS and EXCEPT functions and many others.
When browsing the cube and dimensioning [Measures].[Applications TD]
by [Date].[Year - Month - Date]
user-defined hierarchy it is terribly slow.
IIF
is generally faster than CASE
, and SUM
is often faster than AGGREGATE
.
Although your main problem is the second part of your condition using membervalue
- is it required or will the following not do the same thing? :
CREATE MEMBER CURRENTCUBE.[Measures].[Applications TD] AS
IIF(
SUM (
{ NULL : [Date].[Year - Month - Date].CurrentMember }
,[Measures].[Applications]
) < 0
, NULL
,
SUM (
{ NULL : [Date].[Year - Month - Date].CurrentMember }
,[Measures].[Applications]
)
)
I'd separate this out as a custom member:
CREATE MEMBER CURRENTCUBE.[Date].[Date].[All].[Today] AS //<< a little of syntax for this create
StrToMember('[Date].[Date].&['+Format(Now(),"yyyy-MM-ddT00:00:00")+']')
Then try a nested IIF
:
CREATE MEMBER CURRENTCUBE.[Measures].[Applications TD] AS
IIF(
[Date].[Year - Month - Date].CurrentMember.MemberValue >= [Date].[Date].[All].[Today].MemberValue
, NULL
, IIF(
SUM (
{ NULL : [Date].[Year - Month - Date].CurrentMember }
,[Measures].[Applications]
) < 0
, NULL
,
SUM (
{ NULL : [Date].[Year - Month - Date].CurrentMember }
,[Measures].[Applications]
)
)
)
BUT
Rather than bothering with the "Today" member it will be a lot more efficient if you add an isToday column to DimDate - then have an attribute of the cubes date dimension using the column. That way you should be able to simplify this [Date].[Year - Month - Date].CurrentMember.MemberValue >= [Date].[Date].[All].[Today].MemberValue