Olap cube calculated member, how to round - mdx

I created a calculated member and his value is:
[Measures].[Value]
/
[Measures].[Recuento Fact Result]
I want to round that value, and save only the first two decimals,
for example:
[Measures].[Value]=10
[Measures].[Recuento Fact Result]=3
My calculated member = 3.3333333333333333333
I want to get 3.33
How can I do this?

Try this:
Round(
[Measures].[Value]/[Measures].[Recuento Fact Result]
, 2 //<<you can adjust to the number of dec places required
)
Another interesting rounding function that is used in mdx is Fix
Fix(
[Measures].[Value]/[Measures].[Recuento Fact Result]
)
You'll only get the integer part of the answer returned.
As an aside - you should defend against divide by zero possibilities with a measure like yours like this:
Round(
IIF(
[Measures].[Recuento Fact Result] = 0,
,null
,[Measures].[Value]/[Measures].[Recuento Fact Result]
)
,2
)

Related

Getting results for even years only

MDX has a nice feature whereby I can specify a range of members:
SELECT ([Canada],[2006]:[2011]) on Rows,
[Measures].members on Columns
FROM [Sales]
Is there a way to calculate the set of even years: {[2006], [2008], [2010]}? I am looking for a way that would work for large sets, so that listing the years manually is not an option.
You can filter you function using a filter function, a declared function and MOD function (MOD returns the remainder from the division - like % in Java ) :
WITH
FUNCTION isEven(Value _number) as Mod( Int(_number) , 2 ) = 0
SELECT
FILTER( [Date].[Date].[Year] as t, isEven( Year( t.current.key) ) ) on 0
FROM [Cube]
If you are using this filter often you could create a FilterEven declared function once in the script (same for isEven() )
Try this. I used adventure works for the query.For the mod logic i took help from
Mod Logic
WITH
MEMBER [Measures].[Data Type] AS
[Date].[Day of Year].CurrentMember.Properties ("Member_Value",TYPED)
MEMBER [Measures].[IsEven] as
[Measures].[Data Type]-Int([Measures].[Data Type]/2)*2
select {[Measures].[Internet Order Count] }
on columns,
filter (
[Date].[Day of Year].[Day of Year],
[Measures].[IsEven]=0)
on rows
from [Adventure Works]
Plus you can have a column in the date dimension have 1,0 to indicate if the year is even or odd. Then simply use that column in the MDX query , no need to do all the above manipulations

MDX: Linkmember > Descendants offsets with currentmember context

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]
)

Test whether member exists in dimension

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]
)
)

Filtering a SET with two dimensions

I have a fact table say WhsFactJob where we have CreatedTimeKey and InProgressTimeKey and I have a measure where Job Count.
I am trying to create a Calculated measure which will fetch me the job count whose CreatedTimeKey falls between 1(1:00 AM) and 2(2:00 AM) and InProgressTimeKey also falls with the same 1(1:00 AM) and 2(2:00 AM).
I tried to use SUM and Except, But it errors out saying Except has to use the same hierarchy.( CreatedTimeKey and InprogressTime Key are two seperate dimensions.
Any suggestions would help.
Here is the MDX example I am trying out.
WITH
MEMBER [Measures].[Sum] AS
SUM(
EXCEPT(
{[Created Time].[Hour].&[0]:[Created Time].[Hour].&[14]},
{[In Progress Time].[Hour].&[0]:[In Progress Time].[Hour].&[14]}
)
,[Measures].[Job Count]
)
SELECT
[Measures].[Sum] ON 0
FROM [Cube]
I'm not clear why you're using EXCEPT. How about this:
SUM
(
CROSSJOIN(
{[Created Time].[Hour].&[0]:[Created Time].[Hour].&[14]},
{[In Progress Time].[Hour].&[0]:[In Progress Time].[Hour].&[14]}
)
,[Measures].[Job Count]
)
I think you can get rid of the exception by cross-joining each set to members from the other set: not sure if the result of the query will be useful though - currently I'm unable to test the following:
The dimensionality of the two sets of tuples within the EXCEPT function should now be the same:
WITH
MEMBER [Measures].[Sum] AS
SUM(
EXCEPT(
{[Created Time].[Hour].&[0]:[Created Time].[Hour].&[14]}
*[In Progress Time].[Hour].[Hour].MEMBERS
, [Created Time].[Hour].[Hour].MEMBERS
*{[In Progress Time].[Hour].&[0]:[In Progress Time].[Hour].&[14]}
)
,[Measures].[Job Count]
)
SELECT
[Measures].[Sum] ON 0
FROM [Cube];

SSAS Calculated Member for measures that have the same Dimension

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]