This should be simple, I just can't figure out how to do it.
I'm making a calculated measure, which uses the PrevMember in a time dimension. I'd like to show NULL if the [Time dimension].CurrentMember has no PrevMember.
I just can't figure out what to wrap around this member expression to say "does this member actually exist?". I'm not interested in whether a particular measure exists against this .PrevMember (i.e. EXISTING or EXISTS). I don't want to refer to the measures dimension - just test whether [Time dimension].CurrentMember.PrevMember returns any member at all within the dimension.
EDIT
The calculated measure in question is
([ThisPeriod]-PriorPeriod)/PriorPeriod
so I want to catch the cases where there is no prior period (at every level of the time hierarchy) and force the result to 0 rather than getting some kind of (div/0?) error.
This produces 0 where the CurrentMember does not have a Previous Member, at all levels.
WITH MEMBER [Measures].[ThisPeriod] AS 3
MEMBER [Measures].[PriorPeriod] AS 2
MEMBER [Measures].[NewMeasure] AS
IIF([Date].[Calendar].CURRENTMEMBER.PREVMEMBER IS NULL,0,[Measures].[ThisPeriod] - [Measures].[PriorPeriod])
SELECT
{[Measures].[ThisPeriod], [Measures].[PriorPeriod], [Measures].[NewMeasure]} ON COLUMNS
, [Date].[Calendar].MEMBERS ON ROWS
FROM
[Adventure Works]
;
Not sure you need to do anything - if there is no previous member then null will just get returned anyhow?
WITH
MEMBER Measures.[CalendarPrevious] AS
[Date].Calendar.CurrentMember.PrevMember.Member_Caption
MEMBER Measures.[CalendarPrevious2] AS
IIF
(
Count({[Date].Calendar.CurrentMember.PrevMember}) = 1
,[Date].Calendar.CurrentMember.PrevMember.Member_Caption
,null
)
SELECT
NON EMPTY
{
Measures.[CalendarPrevious]
,Measures.[CalendarPrevious2]
} ON 0
,[Date].[Calendar].[Date].MEMBERS ON 1
FROM [Adventure Works];
Returns:
To combat div errors I generally use this pattern:
MEMBER [Date].[Date - Calendar Month].[All].[DlyAvgGrowth] AS
IIF
(
[Date].[Date - Calendar Month].[All].[PrevMth_DlyAvg] = 0
,NULL
,Divide
(
[Date].[Date - Calendar Month].[All].[CurrentMth_DlyAvg]
-
[Date].[Date - Calendar Month].[All].[PrevMth_DlyAvg]
,[Date].[Date - Calendar Month].[All].[PrevMth_DlyAvg]
)
)
Related
I'm self taught in MDX and am struggling with a problem.
I need to be able to isolate a set of products according to a window around their release date and then calculate their sales by the current rows date context. The 'window' is a set of streetdates where member is between or equal to currentmember -27 and currentmember + 7 (as we sometimes see early sales/preshipping).
Final output should look something like (forward days blank):
NR Sales
2018-03-25 117.12
2018-03-26 130.01
2018-03-27 2,827.63
2018-03-28
2018-03-29
2018-03-30
2018-03-31
My cube has a street/release date hierarchy which is a mirror of my fiscal date hierarchy. It pulls correct values with a slightly altered query looking at a single day in the where clause.
The below query returns values, but is slightly incorrect as i think the descendants call isn't working properly.
WITH
SET [StreetDateSet] AS
LinkMember
(
Descendants
(
[Date].[Yr-Qtr-Mo-Wk-Day].CurrentMember
,[Date].[Yr-Qtr-Mo-Wk-Day].[Day]
).Item(0)
,[Street Date].[StreetDate-Yr-Mo-Wk-Dy]
).Lag(27)
:
LinkMember
(
Descendants
(
[Date].[Yr-Qtr-Mo-Wk-Day].CurrentMember
,[Date].[Yr-Qtr-Mo-Wk-Day].[Day]
).Item(0)
,[Street Date].[StreetDate-Yr-Mo-Wk-Dy]
).Lag(-7)
MEMBER [NR Sales] AS
Sum
(
[StreetDateSet]
,[Measures].[Sales Value]
)
SELECT
NON EMPTY
[NR Sales] ON 0
,[Date].[Date].Children ON 1
FROM [CUBE]
WHERE
(
[Date].[Yr-Qtr-Mo-Wk-Day].[Week].&[2018]&[2]&[4]
,[Item].[New Used].[New]
,{
[Item].[Category Code].[220]
,[Item].[Category Code].[230]
,[Item].[Category Code].[210]
}
);
I suspect there's a few problems here but am not sure how to address them. Descendants is likely impacted by the date hierarchy in the where clause. I've tried to get it into the 1 axis, but i get 'The Yr-Qtr-Mo-Wk-Day hierarchy already appears in the Axis1 axis.' and am unsure how to address.
Thanks for any advice/guidance on where i'm going wrong.
Turns out that linkmember wasn't required and ended up finding a solution via MSDN that uses a filter/Properties function:
Set iteration in calculation
Solution involves a member which iterates a NULL * CurrentMember defined set and I slightly adopted the statement to generate a dynamic set which matches off the complementary hierarchies.
WITH
MEMBER [Measures].[SameDay] AS
NULL * Count([Date].[Yr-Mo-Wk-Day].CurrentMember AS MySet)
+
Sum
(
{
Filter
(
[Street Date].[StreetDate-Yr-Mo-Wk-Dy].MEMBERS AS MySet2
,
MySet2.Current.Properties("Key") = MySet.Item(0).Properties("Key")
).Item(0).Lag(28)
:
Filter
(
[Street Date].[StreetDate-Yr-Mo-Wk-Dy].MEMBERS AS MySet2
,
MySet2.Current.Properties("Key") = MySet.Item(0).Properties("Key")
).Item(0).Lead(7)
}
,[Measures].[Sales Value]
)
I have the following MDX query which computes the Active Opportunities asofdate(defined by greater than start date and less than close date)
This works when the date values are hard coded. But I want it to work with .currentmember which takes the member in the hierarchy and computes the open opportunities between two dates
with member
[Measures].[Cumulative_count_dates]
as
AGGREGATE(
{NULL:[Time Dimension].[Year-Qtr-Month-Date].[Date].&[2011-10-09T00:00:00]} * {[Opportuntity Close Dt].[Year-Qtr-Month-Date].[Date].&[2011-10-11T00:00:00] : NULL}
, [Measures].[Opportunities Count]
)
select {[Measures].[Cumulative_count_dates]} on columns,
NON EMPTY {[Time Dimension].[Year-Qtr-Month-Date].members} on rows
from AdventCube
In other words, I want to pass this as a variable
[Time Dimension].[Year-Qtr-Month-Date].[Date].&[2011-10-09T00:00:00]
Please help.
What's wrong with CurrentMember?
with member
[Measures].[Cumulative_count_dates]
as
AGGREGATE(
{NULL:[Time Dimension].[Year-Qtr-Month-Date].CurrentMember} * {[Opportuntity Close Dt].[Year-Qtr-Month-Date].[Date].&[2011-10-11T00:00:00] : NULL}
, [Measures].[Opportunities Count]
)
select {[Measures].[Cumulative_count_dates]} on columns,
NON EMPTY {[Time Dimension].[Year-Qtr-Month-Date].[Date].members} on rows
from AdventCube
I am trying to create a calculated measure that subtracts measures that are in different groups, but only if they have the same dimension member whatever that may be. (edit - essentially exclude UnknownMember numbers in the subtraction)
I have tried using Scope:
CREATE MEMBER CURRENTCUBE.[Measures].[CalcField] as NULL;
SCOPE([Dimension1].[DimensionField1].MEMBERS);
[Measures].[CalcField] = [Measures].[a] - [Measures].[b];
END SCOPE;
I have also tried using a Tuple without success:
CREATE MEMBER CURRENTCUBE.[Measures].[CalcField]
AS ([Measures].[a] - [Measures].[b], [Dimension1].[DimensionField1]);
But I think there is something fundamental that I am missing
Edit
col a b dimension
1. 9 0 x
2. 0 2 x
3. 1 5 null
If you aggregate those rows I want the answer 7 not 5
Using a simple CASE WHEN works if the dimensions in use, but otherwise it blindly subtracts everything again
CASE
WHEN [Dimension1].[DimensionField1] IS [Dimension1].[DimensionField1].UnknownMember THEN 0
ELSE [Measures].[a] - [Measures].[b]
END
Using Aggregate works at the high level, but then when I use the Dimension I get no per member results
Aggregate(
EXCEPT(
[Dimension1].[DimensionField1].Members, {[Dimension1].[DimensionField1].UnknownMember, [Dimension1].[DimensionField1].[All]}
),[Measures].[a])
-
Aggregate(
EXCEPT(
[Dimension1].[DimensionField1].Members, {[Dimension1].[DimensionField1].UnknownMember, [Dimension1].[DimensionField1].[All]}
),[Measures].[b])
Workaround Solution
I am sorry if I was not clear on my problem, but I have ended up solving this problem by putting the data I need in at the ETL stage rather than calculating it in the Cube
Did you try either Summing or Aggregating your second snippet?
CREATE MEMBER CURRENTCUBE.[Measures].[CalcField]
AS
Sum(
[Measures].[a] - [Measures].[b],
[Dimension1].[DimensionField1]
);
CREATE MEMBER CURRENTCUBE.[Measures].[CalcField]
AS
Aggregate(
[Measures].[a] - [Measures].[b],
[Dimension1].[DimensionField1]
);
With Member [Measures].[CalcField] as [Measures].[a] - [Measures].[b]
Select [Measures].[CalcField]
on columns,
[Dimension1].[DimensionField1].MEMBERS
on rows
from [cube]
I am using Performance Point Dashboard Designer 2013 and SharePoint Server 2013 for building dashboards. I am using SSAS2012 for Cube.
I have a scenario similar to the one illustrated by figure below. I am required to find Previous Non-Empty value for purpose of finding Trends.
Measure: [Quota]
Dimension: [Date].[Calendar Date].[Date]
The script ([Measures].[Quota], [Date].[Calendar Date].PrevMember) gives you a previous date. Lets say for date 27-Jan-13 whose Quota value is 87, it returns 26-Jan-13 which has null value. I want it to return 21-Jan-13 that has some Quota value. And for date 21-Jan-13, I want to return 15-Jan-13.
I wonder if this is possible.
Thanks,
Merin
After long searches and hits & trials and so on, I think I invented a solution of my own for myself.
Following is the script for my Calculated Member.
(
[Quota],
Tail
(
Nonempty
( LastPeriods(15, [Date].[Calendar Date].PrevMember)
,[Quota]
)
).Item(0)
)
Explanation
The number 15 means it will look for non-empty measures up to 15 siblings.
Now we know up to how many siblings to traverse back, in this case 15.
Lets find 15 previous siblings (both empty and non-empty) excluding current member.
(LastPeriods(15, [Date].[Calendar Date].PrevMember)
Since it will yield both empty and non-empty members, lets filter out empty members in terms of measure [Quota]. If we don't specify measure here, it will use default measure whatever it is and we may not get desired result.
Nonempty(LastPeriods(15, [Date].[Calendar Date].PrevMember),[Quota])
We may have several members in the output. And we will choose the last one.
Tail
(
Nonempty
( LastPeriods(15, [Date].[Calendar Date].PrevMember)
,[Quota]
)
)
So far, the script above gives previous non-empty member. Now we want to implement this member for our measure [Quota].
Hence we get the script below ready to create a Calculated Member.
(
[Quota],
Tail
(
Nonempty
( LastPeriods(15, [Date].[Calendar Date].PrevMember)
,[Quota]
)
).Item(0)
)
You can use recursion to define this.
The following query delivers something similar for the Adventure Works cube:
WITH member [Measures].[Prev non empty] AS
IIf(IsEmpty(([Date].[Calendar].CurrentMember.PrevMember, [Measures].[Internet Sales Amount])),
([Date].[Calendar].CurrentMember.PrevMember, [Measures].[Prev non empty]),
([Date].[Calendar].CurrentMember.PrevMember, [Measures].[Internet Sales Amount])
), format_String = '$#,##0.00'
SELECT {[Measures].[Internet Sales Amount], [Measures].[Prev non empty]}
ON COLUMNS,
non empty
Descendants([Date].[Calendar].[Month].&[2007]&[12], [Date].[Calendar].[Date])
ON ROWS
FROM [Adventure Works]
WHERE [Customer].[Customer].&[12650]
You would have to replace the name of the date hierarchy, as well as the measure name from Internet Sales Amount to Quota in the recursive definition of the measure Prev non empty.
I am developing a query builder application that generates MDX and trying to get customer counts from a cube using the following, which works just fine:
WITH MEMBER MEASURES.X AS (
{ [Customer].[Gender].[Female]},
[Customer].[Customer].Children
).Count
SELECT Measures.X ON 0 FROM [Adventure Works]
However, if the user drags in a dimension that is not related to the customer like:
WITH MEMBER MEASURES.X AS (
{ [Customer].[Gender].[Female]},
{ [Employee].[Status].[Active], [Employee].[Status].[Inactive]},
[Customer].[Customer].Children
).Count
SELECT Measures.X ON 0 FROM [Adventure Works]
the count result obviously becomes incorrect.
Is there a way to determine whether a dimension is related to the customer so that I can exclude it from the generated MDX query?
This information can be retrieved from the cube through AMO. The Cube class contains all the cube metadata you'll need.
Solved the problem by using the Exists( Set_Expression1 , Set_Expression2 [, MeasureGroupName] ) function. No need to manually determine which dimensions are related. The Exists function filters out the unrelated tuples, leaving only the
{ [Customer].[Customer].Children, [Customer].[Gender].[Female]} set to do the count over.
Here is the MDX:
WITH MEMBER MEASURES.X AS Exists(
[Customer].[Customer].Children,
{[Customer].[Gender].[Female]}
*
{[Employee].[Status].[Active], [Employee].[Status].[Inactive]}
).Count
SELECT Measures.X ON 0 FROM [Adventure Works]