Adding an extra row to an MDX result set - ssas

I have a very simple MDX query that retuns the contents of a dimension.
I would like to inject one more row to the result set as part of the MDX.
Is this possible?

You can create a calculated member of the dimension. Suppose I have 4 members of region built into my cube: East, West South and Central.
SELECT
{[Profit].[Sales]} ON COLUMNS,
NON EMPTY [Market].Generations(2).Members ON ROWS
FROM [Basic]
will give me the sales over the 4 regions.
If I add a dummy calculated member to the region, I can get one extra row of results.
WITH
MEMBER [Market].[Dummy] AS
'0',
SOLVE_ORDER = 0
SELECT
{[Margin].[Sales]} ON COLUMNS,
NON EMPTY Union(
[Market].Generations(2).Members,
{[Market].[Dummy]}) ON ROWS
FROM [Basic]

no, it has to be a member of some dimension

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: Calculate percentage from a measure present in the same dimension

I am learning MDX and I have a question to create a percentage.
Basically, I extract data from Google Analytics API for multiple sets of pages.
For each set, I extract the number of UniquePageviews.
The SQL columns looks like that:
date
deviceCategory
medium
uniquePageviews
transactions
set_of_page (the rows contain the name of the set of pages. To simplify: 1. First, 2. Second, 3. Third )
Brand (Brand A, Brand B)
Market (Market X, Market Y)
Here is the current view I have:
http://i.stack.imgur.com/ZTC30.png
What I want to have is the percentage of UniquePageviews from the set of page 1 to 2 and from 2 to 3 So: UniquePageviews 2/Uniquepageviews 1 & UniquePageviews 3/Uniquepageviews 2.
http://i.stack.imgur.com/xf2gc.png
Do you know a simple way to do that in MDX?
Here is the code I have for now to display the pageviews:
WITH
SET [~COLUMNS_Brand_Brand] AS
SET [~COLUMNS_Market_Market] AS
{[Market].[Market].Members}
SET [~COLUMNS_set_of_page segment_set_of_page] AS
{[set_of_page].[set_of_page].Members}
SET [~ROWS] AS
{[Date].[Date].Members}
SELECT
NON EMPTY NonEmptyCrossJoin([~COLUMNS_Brand_Brand], NonEmptyCrossJoin([~COLUMNS_Market_Market], [~COLUMNS_set_of_page_set_of_page])) ON COLUMNS,
NON EMPTY [~ROWS] ON ROWS
FROM [MySQL_Cube]
Thanks a lot!
At the moment your mdx is picking up the measure implicitly? All mdx queries need something to measure so your current script must be picking up the default cube measure - I'll call this [Measures].[NumTransactions].
Also your first SET seems to be blank. Therefore lets assume the full, explicit script is:
WITH
SET [~COLUMNS_Brand_Brand] AS {[Brand].[Brand].[All]}
SET [~COLUMNS_Market_Market] AS
{[Market].[Market].Members}
SET [~COLUMNS_set_of_page segment_set_of_page] AS
{[set_of_page].[set_of_page].Members}
SET [~ROWS] AS
{[Date].[Date].Members}
SELECT
NON EMPTY NonEmptyCrossJoin([~COLUMNS_Brand_Brand], NonEmptyCrossJoin([~COLUMNS_Market_Market], [~COLUMNS_set_of_page_set_of_page])) ON COLUMNS,
NON EMPTY [~ROWS] ON ROWS
FROM [MySQL_Cube]
WHERE [Measures].[NumTransactions];
I use MS SSAS so a little unsure of nitation that works with you but just to help me I'll switch to the * operator for cross-joins:
WITH
SET [~COLUMNS_Brand_Brand] AS {[Brand].[Brand].[All]}
SET [~COLUMNS_Market_Market] AS
{[Market].[Market].Members}
SET [~COLUMNS_set_of_page segment_set_of_page] AS
{[set_of_page].[set_of_page].Members}
SET [~ROWS] AS
{[Date].[Date].Members}
SELECT
NON EMPTY
[~COLUMNS_Brand_Brand]
*[~COLUMNS_Market_Market]
*[~COLUMNS_set_of_page_set_of_page] ON COLUMNS,
NON EMPTY [~ROWS] ON ROWS
FROM [MySQL_Cube]
WHERE [Measures].[NumTransactions];
I'm hoping (as untested and I'm a little unsure all context will be retained) that we can just add a custom meassure that divides the current page by the previous one to get the percentage:
WITH
SET [~COLUMNS_Brand_Brand] AS {[Brand].[Brand].[All]}
SET [~COLUMNS_Market_Market] AS
{[Market].[Market].Members}
SET [~COLUMNS_set_of_page segment_set_of_page] AS
{[set_of_page].[set_of_page].Members}
SET [~ROWS] AS
{[Date].[Date].Members}
MEMBER [Measures].[NumTransactionsPercent] AS
[set_of_page].CURRENTMEMBER
/ [set_of_page].CURRENTMEMBER.LAG(1)
SELECT
NON EMPTY
[~COLUMNS_Brand_Brand]
*[~COLUMNS_Market_Market]
*[~COLUMNS_set_of_page_set_of_page] ON COLUMNS,
NON EMPTY [~ROWS] ON ROWS
FROM [MySQL_Cube]
WHERE [Measures].[NumTransactionsPercent]; //[Measures].[NumTransactions];

Add percentages to an OLAP cube Mondrian schema

I would like to calculate percentage of one of my measures.
For example:
I have a measure with aggregator distinct-count.
I would like to calculate the percentage of that measure, based on the current information.
For example: gender users-distinct-count percentage
male 25 25% (25/100)
female 41 41% (41/100)
unk 34 34% (34/100)
But, if I filter out unk, I want the percentage to be out of 25+41, i.e. 66
gender users-distinct-count percentage
male 25 37.8% (25/66)
female 41 %62.2 (41/66)
I also want, that when viewing the data with different dimensions, the total sum will be updated accordingly.
I tried this:
<CalculatedMember name="user_percentage" caption="Users Percentage"
formula="[Measures].user_count/ ([Measures].user_count,[dim1].[All Dim1],[dim2].[All Dim2])" dimension="Measures" visible="true">
</CalculatedMember>
but, when filtering values on the dimensions (like removing the
"unk", the total remains the same (over all dim).
Thanks,
You should do it at the client level, not the schema level.
The schema has no idea what you're querying on your rows or columns, only the client does.
Some client tools allow you to create a calculated measure as a % of the visible values, but that has to be done by the query.
Example:
With
SET ROWSET as {[Gender].[Male],[Gender].[Female]}
MEMBER [Gender].[Visible] as Aggregate( ROWSET, [Measures].[user_count] )
MEMBER [Measures].[Percentage] as ( [Measures].[user_count], [Gender].CurrentMember ) / ( [Measures].[user_count], [Gender].[Vislble] )
SELECT
ROWSET on Rows,
{ [Measures][user_count], [Measures].[Percentage] } on Columns
FROM [My Cube]
As you must reference the set selected on rows when defining the percentage, you cannot define it at the schema level.

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]