MDX Statement explaination required - ssas

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:

Related

How to concatenate hidden cube dimension and measure with an MDX query?

I have a cube with three (relevant) dimensions (quarter, element and qualifier). The measure of interest is score, which is numeric.
The qualifier dimension is sparse, i.e. for each unique combination of quarter and element, the measure score is reported only for one qualifier, for the other members of the qualifier dimension the measure score is blank. Which qualifier is 'active' entirely depends on the quarter and element.
I want to build a table with quarter members as columns and element members as rows. The cell values should be the concatenation of the score measure and the name of that qualifier member (string) for which the score at the relevant intersection of quarter, element and qualifier is not blank.
To make matters more complex, one of the member names of the qualifier needs to be replaced with blanks in the table. There are four distinct members, which should be renamed in the table as follows: the member names '+', '-', '' stay as they are, while the name 'No Qualifier' should become blank, i.e. ''.
Below is an example of the structure I would like to get (note that there should be no '+' or '-' in case the corresponding score is reported in either the qualifier members '' or 'No Qualifier'):
2021Q4
2020Q4
2019Q4
Element 1
3
2+
2
Element 2
1
1
1
Element 3
2
3
2+
Element 4
2-
2-
3
I suppose I would need to create a calculated member, but so far I only get the concatenation and replacement to work with the currentmember function if I include the qualifier dimension explicitly in either rows or columns, which however is not a feasible output structure. Also, changing the underlying cube is not possible (it is maintained by IT).
I am new to cubes and MDX and have already spent two days trying to figure this out by myself. Since this is a work project, I am starting to panic. Any help would really be appreciated!

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.

Not Specifying an Axis

I am trying to write an MDX Code which has all the members of my cube in the row. However when I specify the row, it mentions that I must ALSO specify Columns. But if I do not set an ON ROW nor an ON Column, my code does not validate.
How do I put all my members in a row, and have a single data column be returned?
In mdx ON COLUMNS is axis 0 and ON ROWS is axis 1. For an mdx statement to be valid it must have at least an axis 0 .... this is one of the rules of the language, no getting around it.
Quite often if I need lots of information in my ON ROWS but the columns needs to be a single column then I will select a dimension I am not using e.g. Language, and then use that selected dimensions ALL member for COLUMNS - just to obey the rule. e.g.
SELECT
[Language].[Language].[All] ON 0, //<<JUST A DUMMY ENTRY BUT MUST BE AN ALL MEMBER OF A DIMENSION
...
...

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.

Create dynamic calculated member based on dimensions selected ON ROWS

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]