Slicing inside of a calculated measure defintion? (MDX) - ssas

I have a many-to-many relationship between dimension D and measure M.
I need to create a generic calculated measure that would have the following formula: M/Σ(M), where Σ stands for the sum of all measure's facts that are associated with at least one member of a given dimension.
It's easy for other (one-to-many) dimensions, but getting Σ in many-to-many... well, if it was just a regular MDX query, that would be easy as well. I could just slice on all children of a dimension:
SELECT [Measures].[M] ON 0
FROM [MyCube]
WHERE [D].[All].CHILDREN
But how do I slice in a calculated measure?
A simplified example of what I would expect to work:
CREATE MEMBER [Measures].[Calc] AS
[Measures].[M] / ( DRILLUPLEVEL( AXIS( 1 ).ITEM( 0 ).HIERARCHY.MEMBERS ).ITEM( 0 ), [Measures].[M] )
WHERE DRILLUPLEVEL( AXIS( 1 ).ITEM( 0 ).HIERARCHY.MEMBERS ).ITEM( 0 ).CHILDREN
But of course, MDX doesn't support a WHERE clause in MEMBER definitions.
Please advise me how to approach this.

How about using the aggregate method ?
CREATE MEMBER [Measures].[Calc] AS
[Measures].[M] / Aggregate( DRILLUPLEVEL( AXIS( 1 ).ITEM( 0 ).HIERARCHY.MEMBERS ).ITEM( 0 ).CHILDREN, [Measures].[M] )

In the end, this is what I got:
CREATE HIDDEN [Total M] =
AGGREGATE(
DESCENDANTS(
AXIS( 1 ).ITEM( 0 ).DIMENSION.LEVELS( 0 ).ITEM( 0 ),
AXIS( 1 ).ITEM( 0 ).DIMENSION.LEVELS.COUNT
) - AXIS( 1 ).ITEM( 0 ).DIMENSION.LEVELS( 0 ).ITEM( 0 ),
[Measures].[M]
);
In short, I subtracted the root member from the set of the dimension's members. Aggregating over the remaining set gives proper value in many-to-many relationships. I can now use this measure in other measures to calculate M/Σ(M), etc.

Related

How to multiply two measures prior to aggregation

I have two measures. The first is amount, and the second consist of values -1,0 and 1, so table looks like this:
Amount Sign
--------------
400 -1
200 1
300 0
Result I want to get is 400*(-1) + 200*1 + 300*0 = -200, but I am getting (400+200+300)*(-1+1+0) = 0
This is my calculated member:
WITH
MEMBER [Measures].[Result]
AS
[Measures].[Sign]*[Measures].[Amount]
select
[Measures].[Result] on 0,
[Time].[Time].members on 1
from [MyCube]
In you SSAS project, go to the datasource view, for the underlying fact table add a NamedCalculation. In that do the multiplication that you explained. Now in the Cube add that as a measure. It will behave exactly like you want it to behave.

Powerpivot - Only Show Minimum Value

Newbie to DAX/PowerPivot and struggling with a specific problem.
I have a table
Location Category Distance
1 A 1.244
2 A 2.111
3 B 5.113
4 C 0.124
etc
I need to identify the Minimum distance out of the selection and only output for that record. So I'd have
Location Category Distance MinDist
1 A 1.244
2 A 0.111 0.111
3 B 5.113
4 C 3.124
etc
I've tried various measures but always end up with simply a repeat of the Distance column....whatever filters I try to apply.
Please help.
If your table was called 'table1' then this would give you the overall minimum:
=CALCULATE(MIN(Table1[Distance]), ALL(Table1))
Depending on your requirements, you may have to specify columns in the ALL() to reduce how much of the filter is opened up (suggest you research ALL() as it is a very important DAX function).
To return zero (blanks is tricky) for the non matchers you could package it in:
=
IF (SUM ( Table1[Distance] ) = CALCULATE ( MIN ( Table1[Distance] ), ALL ( Table1 ) ),
CALCULATE ( MIN ( Table1[Distance] ), ALL ( Table1 ) ),
0
)

Mdx - Flag -Actual

I have two dimensions DimFlag and DimPNL and a fact table FactAmount. I am looking to:
When pnl is stat(Is Stat=1) : sum (Actual x FlagId)
For pnl I multiply the amounts by field FlagId basically if it will be so 0 0 X = 0 ...
DimFlag
FlagId FlagLabel
-----------------
1 NotClosed
0 IsClosed
DimPNL
PNLId PNLName Is Stat
1 a 1
2 test 1
3 test2 0
FactAmount
id PNLId FlagId Actual
1 1 1 100
2 2 1 10
3 3 0 120
I tried the following MDX but it didn't work, any idea please ?
Scope (
[Dim PNL].[PNL].members,[Measures].members
);
this = iif([Dim PNL].[PNL].CurrentMember.Properties("Is Stat") =1
,
aggregate([Dim PNL].[PNL].currentmember,[Measures].currentmember)* iif([Dim Flag].[Flag Label].[Flag Label].currentmember = 0, 0, 1),
aggregate([Dim PNL].[PNL].currentmember,[Measures].currentmember)
);
While this type of calculation can be done in MDX, the MDX can get complex and performs bad. I would suggest to explicitly do the calculation e. g. in the DSV or a view on the fact table that you then use instead of the fact table directly in the DSV. The result of the calculation would then be another column on which you can base a standard measure.
To do it in the DSV, assuming you use a relational table as the base for the fact table, add a named calculation to it, define the column name however you like, and use the expression Actual * FlagID. For the other calculation, you may need a subselect, i. e. the expression would be Actual * case when pnlId in(1,2) then 1 else 0 end. You can use any SQL that works as a column expression in the select list as the expression in for a named calculation.
Implementing the same in a view on FactAmount, you could implement the second expression better, as then you could join table DimPNL in the view definition and thus use column IsStat in the calculation. Then you would replace table FactAmout by the view, which has the two additional measure columns.
In either case, just define two measures on the two new columns in the cube, and you are done.
As a rule, calculations that are done on record level in the fact table before any aggregation should be done at data loading time, i. e. as described above.

MDX: Showing a zero count for non-existing members

I'm still a newbie at MDX, so maybe this will be a simple question.
I want to do something like see sales revenue by product: more specifically, products are classified in "classes" (where class can be A,B or C), so I want to see the amount of sales of class A products, class B and so on. If the Dimension "Product" has one Hierarchy "Classification" with level "Class", suppose the MDX query, for the sake of simplicity, is as follows:
SELECT
[Measures].[Sales] on COLUMNS,
[Product].[Classification].[Class].members on ROWS
FROM [Cube]
Problem is, if there's no record with class='C',for example, in Data table Product, there will be no member 'C', right? In that case, I'd like to show a zero count for that. So, instead of having:
| Sales
A 1000
B 200
I'd like:
| Sales
A 1000
B 200
C 0
Any help?
Thanks in advance!
Problem is, if there's no record with class='C',for example, in Data
table Product, there will be no member 'C', right?
As your select does not contain NON EMPTY ... ON ROWS, then 'C' should be returned with an empty cell as its 'Sales' value. It is possible that your 'client' tool is then ignoring it.
What you can do is define a calculated measure using the CoalesceEmpty() function to return a ZERO value instead of empty :
WITH
MEMBER [Measures].[Sales - X] as
CoalesceEmpty( ( [Measures].[Sales] ).Value, 0 )
SELECT
[Measures].[Sales - X] on COLUMNS,
[Product].[Classification].[Class].members on ROWS
FROM [Cube]

MDX query "with member" and sum problem

I have a query like
WITH MEMBER [measures].[Count] AS
SUM(([Location].[Hierarchy].[Zone].[1].Children),[Measures].[Length])
SELECT {[measures].[Count]} ON 0,
{[Location].[Hierarchy].[Zone].&[1].Children} on 1
FROM [NTAP]
I'm a real beginner with MDX but from my understanding this should get me a list with all Zone 1:s children and a sum of all those children Length summarized. The problem is I get a list with the children and a sum of all Zone 1:s Length?
I get this:
1 103026769420
2 103026769420
3 103026769420
4 103026769420
But what I would like to get is something like this
1 84984958
2 9494949
3 934883
4 9458948588
Location is a hierarchy like:
Zone Children
1
1
2
3
2
1
2
3
edit: should probably say that the reason I use with member is that the measure.length will with a Iif in the final version. But I cant even get this working :(
edit2: fixed spelling
You are getting the sum of all children of Zone 1 for each child of Zone 1.
You can rewrite it as:
WITH MEMBER [Measures].[Count] AS
SUM([Location].[Hierarchy].CurrentMember.Children, [Measures].[Length])
SELECT {[Measures].[Count]} ON 0,
{[Location].[Hierarchy].[Zone].&[1].Children} on 1
FROM [NTAP]
By the way, [1] <> &[1]. Without the & you are specifying the name and with - the key. If in your case key = name you have nothing to worry about.
A query counting the children with L > 0 would be:
WITH
MEMBER [Measures].[Count of Children with L more than 0] AS
FILTER([Location].[Hierarchy].CurrentMember.Children,
[Measures].[Length] > 0).COUNT
SELECT
{
[Measures].[Count of Children with L more than 0]
} ON 0,
{
[Location].[Hierarchy].[Zone].&[1]
} ON 1
FROM [Your Cube]
This of course won't work if you select the children on rows as then you'd get NULLs as they are leaves and have no children themselves.