Create dynamic calculated member based on dimensions selected ON ROWS - mdx

Is there a way to create a dynamic calculated member based on the dimension selected ON ROWS?
I have the following example with 2 dimensions [Dim1].[Dim1] and [Dim2].[Dim2], with a measure [Measures].[Measure] and a calculated member [Measures].[CalculatedMeasure]:
WITH MEMBER [Measures].[CalculatedMeasure] AS
IIF([Dim1].[Dim1]**.....IS SELECTED ON ROWS.........**,
[Measures].[Measure]
/
([Measures].[Measure], [Dim1].[Dim1].CurrentMember.Parent),
[Measures].[Measure]
/
([Measures].[Measure], [Dim2].[Dim2].CurrentMember.Parent))
SELECT {[Measures].[Measure],[Measures].[CalculatedMeasure]} ON COLUMNS ,
{[Dim2].[Dim2].Members)} ON ROWS
FROM [DataBase]
What I want is that when I select [Dim2].[Dim2] ON ROWS, the calculated member should be the result of
[Measures].[Measure]
/
([Measures].[Measure], [Dim2].[Dim2].CurrentMember.Parent)
ELSE
[Measures].[Measure]
/
([Measures].[Measure], [Dim1].[Dim1].CurrentMember.Parent)
Thanks

In Analysis Services, your [Dim1].[Dim1]**.....IS SELECTED ON ROWS.........** could be coded as
Axis(1).Item(0).Item(0).Hierarchy IS [Dim1].[Dim1]
if you can assume there is only one hierarchy on the rows.
Here, Axis(1) returns the rows axis as set. I am not sure if this function is supported by Pentaho/Mondrian. Then, the first Item(0) selects the first tuple of this set, and the second one returns the first member of that tuple. Finally, the Hierarchy function returns the hierarchy of a member.
To extend this to queries containing up to three hierarchies in the rows, you would write
Axis(1).Item(0).Item(0).Hierarchy IS [Dim1].[Dim1] OR
Axis(1).Item(0).Item(1).Hierarchy IS [Dim1].[Dim1] OR
Axis(1).Item(0).Item(2).Hierarchy IS [Dim1].[Dim1]

Related

MDX Result Count

I am a beginner in MDX queries. Can any one tell me how to get the record count that is a result of a MDX query?
The query is following:
select {[Measures].[Employee Department History Count],[Measures].[Rate]} on columns, Non Empty{{Filter([Shift].[Shift ID].[Shift ID].Members, ([Shift].[Shift ID].CurrentMember.name <> "1"))}*{[Employee].[Business Entity ID].[Business Entity ID].Members}} on rows from [Adventure Works2012].
I have tried various methods and I haven't really got a solution for that.
I assume you mean row count when you talk of "record count", as MDX does not know a concept of records, but the result shown from an MDX query is the space built by the tuples on the axes.
I see two possibilities to get the row count:
Just count the rows returned from your above query in the tool from which you call the MDX query.
If you want to count in MDX, then let's state what you want to have:
You want to know the number of members of the set of non empty combinations of [Shift ID]s and [Business Entity ID]s where the Shift ID is not "1" and at least one of the measures [Employee Department History Count] and [Rate] is not null.
To state that different: Let's call the tuples like above for which the first measure is not null "SET1", and the tuples like above for which teh second measure is not null "SET2". Then you you want to know the count of the the tuples which are contained in one of these sets (or in both).
To achieve this, we define these two sets and then a calculated menber (a new measure in our case) containing this calculation in its definition, and then use this calculated member in the select clause to show it:
WITH
SET SET1 AS
NonEmpty({{Filter([Shift].[Shift ID].[Shift ID].Members,
([Shift].[Shift ID].CurrentMember.name <> "1"))}
* {[Employee].[Business Entity ID].[Business Entity ID].Members}},
{[Measures].[Employee Department History Count])
SET SET2 AS
NonEmpty({{Filter([Shift].[Shift ID].[Shift ID].Members,
([Shift].[Shift ID].CurrentMember.name <> "1"))}
* {[Employee].[Business Entity ID].[Business Entity ID].Members}},
{[Measures].[Rate])
MEMBER [Measures].[MyCalculation] AS
COUNT(SET1 + SET 2)
SELECT [Measures].[MyCalculation] ON COLUMNS
FROM [Adventure Works2012]
Please note:
The sets SET1 and SET2 are not absolutely necessary, you could also put the whole calculation in one long and complicated definition of the MyCalculation measure, but splitting it up makes is easier to read. However, the definition of a new member is necessary, as in MDX you can only put members on axes (rows, columns, ...). These members can either already been defined in the cube, or you have to define them in the WITH clause of your query. There is no such thing as putting expressions/calculations on axes in MDX, only members.
The + for sets is a union which removes duplicates, hence this operation gives us the tuples which have an non empty value for at least one of the measures. Alternatively, you could have used the Union function equivalently to the +.
The Nonempty() I used in the definitions of the sets is the NonEmpty function, which is slightly different from the NON EMPTY keyword that you can use on the axes. We use one of the measures as second argument to this function in both set definitions.
I have currently no working SSAS installation available to test my statement, hence there might be a minor error or typo in my above statement, but the idea should work.

MDX: count number of members selected in filter

I have one dimension that I want to put into filter, and created calculated member that should dynamically show number of selected members from the dimension.
The dimension does not have an All member.
So this is my attempt
with member [Measures].[Count1] as count(existing(([MyDimension].[MyDimensionHierarchy].members)))
select [Measures].[Count1] on 0
from [MyCube] -- gives me 1
and this one will give me 2 which is correct:
with member [Measures].[Count1] as count(existing(([MyDimension].[MyDimensionHierarchy].members)))
select [Measures].[Count1] on 0
from [MyCube]
where ({[MyDimension].[MyDimensionHierarchy].[Member1], [MyDimension].[MyDimensionHierarchy].[Member2]})
But, the problem is that when I create calculated member with the formula above, and drag Count1 to the Excel pivot table, and drag MyDimension as filter, and when I do multi-select of the dimension members, I want the count to dynamically change as I change number of members that are selected.
But Count1 always stays equal to 1.
In a meantime I have found an answer:
The query that I wrote in the question actually is not the query that Excel pivot table sends to the cube. Excel pivot table generates query like this:
SELECT FROM (SELECT ({[MyDimension].[MyDimensionHierarchy].[Member1],[MyDimension].[MyDimensionHierarchy].[Member2]}) ON COLUMNS
FROM [MyCube])
WHERE ([Measures].[Count1])
The way this should be done is by using dynamic set that contains filtered members:
create dynamic set [SelectedMembers] as existing( [MyDimension].[MyDimensionHierarchy].members )
And then:
create member Measures.SelectedMembersCount as count([SelectedMembers])
So this set dynamically changes as different members are selected in the filter and SelectedMembersCount is dynamically changed along the way.

MDX Statement explaination required

Please explain the below MDX statement -
Axis(1).Item(0).Item (0).Dimension.Levels(0).item(0)
If possible please share the output as well (using SSMS analysis services)
Axis(1).Item(0).Item(0).Dimension.Levels(0).Item(0)
The way to figure out what this expression means, is to go through each function from left-to-right, and determine what each one is doing and returning. Let's go through this one function at a time.
Axis(1) - Retrieve the set of tuples on the rows axis (the axis at index 1).
Item(0) - Retrieve the first tuple from the previously returned set.
Item(0) - Retrieve the first member from the previously returned tuple.
Dimension - Get the hierarchy from the previously returned member.
Levels(0) - Retrieve the first level from the previously returned hierarchy.
Item(0) - Retrieve the first member from the previously returned hierarchy level.
Here are the Microsoft function definitions that I used to create the above list.
Axis()
Returns the set of tuples on a specified axis.
Item(Tuple)
Returns a tuple from a set.
Item(Member)
Returns a member from a specified tuple.
Dimension
Returns the hierarchy that contains a specified member, level, or hierarchy.
Levels()
Returns the level whose position in a dimension or hierarchy is specified by a numeric expression or whose name is specified by a string expression.
Edit - Added Example
Check out the Geography dimension and hierarchy from the Adventure Works cube.
There are 5 levels for the Geography hierarchy.
[Geography].[Geography].[(All)]
[Geography].[Geography].[Country]
[Geography].[Geography].[State-Province]
[Geography].[Geography].[City]
[Geography].[Geography].[Postal Code]
Let's use your expression on the columns axis (via a calculated member) and select the city, Alexandria, on the rows axis.
WITH
MEMBER [Measures].[SomeMember] AS AXIS(1).ITEM(0).ITEM(0).DIMENSION.LEVELS(0).ITEM(0).MEMBER_CAPTION
SELECT
{([Measures].[SomeMember])} ON COLUMNS,
{([Geography].[Geography].[City].&[Alexandria]&[NSW])} ON ROWS
FROM
[Adventure Works]
Here is the break-down of what's happening:
Axis(1) - Returns the set from the rows axis:
{([Geography].[Geography].[City].&[Alexandria]&[NSW])}
ITEM(0) - Returns the set's first tuple:
([Geography].[Geography].[City].&[Alexandria]&[NSW])
ITEM(0) - Returns the tuple's first member:
[Geography].[Geography].[City].&[Alexandria]&[NSW]
DIMENSION - Returns the member's dimension hierarchy:
[Geography].[Geography]
LEVELS(0) - Returns the hierarchy's first level:
[Geography].[Geography].[(All)]
ITEM(0) - returns the level's first member:
[Geography].[Geography].[(All)].[All Geographies]
Here are the query results:
Here is a screenshot to help visualize where the All Geographies member is, with respect to the Alexandria member:

MDX to show Measure property

I'm familiar with how to get member properties into an MDX result-set: create a calculated member using WITH.
The problem is when the member whose properties I want is a measure, not a dimension member. Because the calculated member is created on the Measures hierarchy, I get the dreaded "The Measures hierarchy already appears in the Axis0 axis" error. Here's the query I'm running:
WITH MEMBER Measures.MeasureType AS
Measures.CurrentMember.Properties('MEMBER_TYPE')
SELECT
MeasureType ON 0,
Measures.Members on 1
FROM TheCube
What I'm after is simply a list of all the measures ON 1 (this works, in itself); but with the measure's MEMBER_TYPE showing as the one column ON 0
You can't have members from the same hierarchy on both axes. There are two ways to get rid of this error.
1. Create the calculated member on some other dimension
WITH MEMBER [SomeDimension].[SomeHierarchy].MeasureType AS
Measures.CurrentMember.Properties('MEMBER_TYPE')
SELECT
[SomeDimension].[SomeHierarchy].MeasureType ON 0,
Measures.Members on 1
FROM [TheCube]
2. Have them in a set and not on different axes.
WITH MEMBER Measures.MeasureType AS
Measures.CurrentMember.Properties('MEMBER_TYPE')
SELECT
{Measures.MeasureType, Measures.Members} ON 0
FROM [TheCube]
Discarding the second method as it gives a static value. What's really needed is a cross-tab value. So sticking with first method.

SSAS 2012 Calculated Member for Percentage

Being an SSAS newbie, I was wondering if it's possible to create a calculated member that references an individual row's value as well as the aggregated value in order to create a percentage?
For example, if I have a fact table with ValueA, I'd like to create a calculate member that essentially performed:
[Measures].[ValueA] (for each row I've sliced the data by) / [Measures].[ValueA] (the total)
Also I'd like to keep the total as the sum of whatever's been filtered in the cube browser. I feel certain this must be possible but I'm clearly missing something.
You can use the Axis function. Her is an example:
WITH MEMBER [Measures].[Percentage] AS
[Measures].[ValueA] / (Axis(1).CurrenMember.Parent, [Measures].[ValueA])
SELECT {[Measures].[ValueA], [Measures].[Percentage]} ON 0,
'what you want' ON 1
FROM your cube
(You may need to add check in the calculated member expression)