Pentaho Mondrian- Hide a dimension value from a role - mdx

I am using Pentaho Mondrian to build a billing cube with the dimensions "country" and "reference".
To one of my roles, I just want to show the reference value when country is equal to "Brazil". If it is not Brazil, reference should be null.
How it is:
http://i.stack.imgur.com/yipPJ.png
How it should be:
http://i.stack.imgur.com/PoF2w.png
How can I do this?
I tryed to use a calculated member with CASE WHEN, but it didnĀ“t work.
Should I use IIF instead?
I code this, but it is not working too:
WITH
MEMBER [dim_reference.Reference].[reference].Members AS
IIF
(
[dim_country.country].[country].CurrentMember = 'Brazil'
,[dim_reference.Reference].[reference].MEMBERS
,''
)
SELECT
NON EMPTY
{Hierarchize({[dim_country.country].[country].MEMBERS})} ON COLUMNS
,NON EMPTY
Order
(
{
Hierarchize({[dim_reference.Reference].[reference].MEMBERS})
}
,[dim_reference.Reference].CurrentMember.Name
,BASC
) ON ROWS
FROM [billing_entry];
Does someone knows how to do this?

A few pointers:
1
So you need to use the IS operator if you want to check for equality with a member.
Rather than this:
[dim_country.country].[country].CurrentMember = 'Brazil'
You use the following - you might need to amend the RHS with the exact full name of your Brazil member:
[dim_country.country].[country].CurrentMember
IS [dim_country.country].[country].[country].[Brazil]
2
Rather than using '' you should use NULL.
Rather than this:
IIF(
<condition>
,<if condition true>
,''
)
You should use this:
IIF(
<condition>
,<if condition true>
,NULL
)
3
You're correct to use IIF rather than CASE if at all possible - IIF generally performs better.
From your screenshots it looks to me that you want Countries ON ROWS rather than ON COLUMNS:
SELECT
NON EMPTY
{} ON COLUMNS
,NON EMPTY
[dim_country.country].[country].MEMBERS ON ROWS
FROM [billing_entry];
Now using SSAS against the AdvWrks cube I can do this:
WITH
MEMBER [Measures].[X] AS
IIF
(
[Customer].[Customer Geography].CurrentMember
IS
[Customer].[Customer Geography].[Country].&[Australia]
,[Product].[Product Categories].CurrentMember.Name
,null
)
SET [s] AS
[Customer].[Customer Geography].[Country]
*
[Product].[Product Categories].[category]
MEMBER [Product].[Product Categories].[All].[calc] AS
[Product].[Product Categories].CurrentMember.Name
SELECT
{[Measures].[X]} ON 0
,[s] ON 1
FROM [Adventure Works];
Which results in this:

Related

MDX - Grand total missing when filtering

I've been working on an ExcelDNA C# xll that allows users to enter simple words (under guidance) and I construct the elaborate MDX for them to query against a remote ActivePivot cube.
During testing I've ntoticed that when filtering, the grand total disappears (presumably it's joining tuples together). How do I still get a grand total? Do I need to use SCOPE or create a calculated member?
Thanks to more advanced MDX people:
SELECT
NON EMPTY
{
[Measures].[Notional.SUM]
,[Measures].[Notional.SHORT]
,[Measures].[Notional.LONG]
} ON COLUMNS
,NON EMPTY
Hierarchize
(
Filter
(
(
[CDR].[CDR].MEMBERS
,[Book].[Book].MEMBERS
)
,
Left([Book].[Book].CurrentMember.MemberValue,2) = "22"
)
,POST
) ON ROWS
FROM [TraderCube]
WHERE
[Date].[Date].[2020-01-24];
The following is something similar against AdvWrks cube:
WITH
//>>inside the WITH clause we have moved the set
SET [FilteredSet] AS
{
Filter
(
[Reseller].[Reseller Type].[Business Type].MEMBERS
,
Left([Reseller].[Reseller Type].CurrentMember.MemberValue,2) = "sp"
OR
Left([Reseller].[Reseller Type].CurrentMember.MemberValue,2) = "VA"
)
}
//>>next we create a custom member that is the sum of the filtered set
MEMBER [Reseller].[Reseller Type].[All Visible Resellers] AS
Aggregate([FilteredSet])
SELECT
NON EMPTY
{[Measures].[Reseller Sales Amount]} ON COLUMNS
,NON EMPTY
//>> inside these curly brackets we declare a set that is the filtered set and the Total member
{
[FilteredSet]
,[Reseller].[Reseller Type].[All Visible Resellers]
} ON ROWS
FROM [Adventure Works]
WHERE
[Date].[Calendar].[Calendar Year].&[2013];
The results of the above is the following:

MDX Query - Select Columns From Same Dimensions

I have a requirement displaying data from same dimension in more than 1 column. For eg. I want to show data Year and Month wise. In my dimension structure, Year and Month belongs to same hierarchy. When I run below query I get error. PFB the query.
Select NON EMPTY {[Measures].[Target Actual Value]} ON 0,
NON EMPTY {[Realization Date].[Hierarchy].[Year Name].Members *
[Realization Date].[Hierarchy].[Month Year]} ON 1
From [Cube_BCG_OLAP]
The error I get is Query (2, 12) The Hierarchy hierarchy is used more than once in the Crossjoin function. I am new to MDX queries. Please help in this regard. Thanks in advance.
Select NON EMPTY {[Measures].[Target Actual Value]} ON 0,
NON EMPTY {[Realization Date].[Hierarchy].[Year Name].Members ,
[Realization Date].[Hierarchy].[Month Year]} ON 1
From [Cube_BCG_OLAP]
Instead of CROSSJOIN have a set as above. In a set, you can put members from same hierarchy
I like Sourav's answer - but it will put the results in one column which is slightly different than the question.
In AdvWorks this is in one column:
SELECT
[State-Province].MEMBERS ON COLUMNS
,{
[Date].[Calendar].[Calendar Year].MEMBERS
,[Date].[Calendar].[Month].MEMBERS
} ON ROWS
FROM [Adventure Works];
It is possible to switch to two columns and use a cross join but you need to find out the details of your Date dimensions Attribute hierarchies (as opposed to User hierarchies):
SELECT
[State-Province].MEMBERS ON COLUMNS
,
[Calendar Year].[All Periods].Children
* [Month].MEMBERS ON ROWS
FROM [Adventure Works];
In your cube maybe something like this:
SELECT
NON EMPTY
{[Measures].[Target Actual Value]} ON 0
,NON EMPTY
[Year Name].MEMBERS
*
[Month Year].MEMBERS ON 1
FROM [Cube_BCG_OLAP];

saiku mdx performance issues with * operator for crossjoin

Can anyone explain why
SELECT
NON EMPTY {Hierarchize({[Measures].[Quantity]})} ON COLUMNS,
NON EMPTY ([Time].[Years].Members * [Markets].[City].Members * [Product].[Product].Members * [Customers].[Customer].Members) ON ROWS
FROM [SteelWheelsSales]
is so much slower than this:
SELECT
NON EMPTY {Hierarchize({[Measures].[Quantity]})} ON COLUMNS,
NON EMPTY CrossJoin([Time].[Years].Members, CrossJoin([Markets].[City].Members, CrossJoin([Product].[Product].Members, [Customers].[Customer].Members))) ON ROWS
FROM [SteelWheelsSales]
I would like to use the * operator to make crossjoins but it seems so much slower. Any idea why and what can I do?
Seems like the order is important:
http://community.altiusconsulting.com.ourwindowsnetwork.com/blogs/altiustechblog/archive/2008/06/13/mdx-crossjoin-performance.aspx
Just in case the above link dies in the future it basically compares the two following AdvWks scripts performance:
QUERY 1
WITH MEMBER Measures.PerfmonTest AS
Count(
Crossjoin( [Promotion].[Promotions].[Promotion] ,
Filter([Customer].[Customer Geography].[Customer], RIGHT([Customer].[Customer Geography].CurrentMember.Name,5) = "Smith")
)
)
SELECT Measures.PerfmonTest ON Columns
FROM [Adventure Works]
QUERY 2
WITH MEMBER Measures.PerfmonTest AS
Count(
Crossjoin(
Filter([Customer].[Customer Geography].[Customer], RIGHT([Customer].[Customer Geography].CurrentMember.Name,5) = "Smith")
,[Promotion].[Promotions].[Promotion] )
)
SELECT Measures.PerfmonTest ON Columns
FROM [Adventure Works]

How can I determine whether dimensions are related?

I am developing a query builder application that generates MDX and trying to get customer counts from a cube using the following, which works just fine:
WITH MEMBER MEASURES.X AS (
{ [Customer].[Gender].[Female]},
[Customer].[Customer].Children
).Count
SELECT Measures.X ON 0 FROM [Adventure Works]
However, if the user drags in a dimension that is not related to the customer like:
WITH MEMBER MEASURES.X AS (
{ [Customer].[Gender].[Female]},
{ [Employee].[Status].[Active], [Employee].[Status].[Inactive]},
[Customer].[Customer].Children
).Count
SELECT Measures.X ON 0 FROM [Adventure Works]
the count result obviously becomes incorrect.
Is there a way to determine whether a dimension is related to the customer so that I can exclude it from the generated MDX query?
This information can be retrieved from the cube through AMO. The Cube class contains all the cube metadata you'll need.
Solved the problem by using the Exists( Set_Expression1 , Set_Expression2 [, MeasureGroupName] ) function. No need to manually determine which dimensions are related. The Exists function filters out the unrelated tuples, leaving only the
{ [Customer].[Customer].Children, [Customer].[Gender].[Female]} set to do the count over.
Here is the MDX:
WITH MEMBER MEASURES.X AS Exists(
[Customer].[Customer].Children,
{[Customer].[Gender].[Female]}
*
{[Employee].[Status].[Active], [Employee].[Status].[Inactive]}
).Count
SELECT Measures.X ON 0 FROM [Adventure Works]

Can I reformulate this MDX query to use sets instead of an "And"?

with member [Measures].[BoughtDispenser] as
Sum(Descendants([Customer].[Customer].CurrentMember, [Customer].[Customer]),
Iif(
(IsEmpty(([Item].[ItemNumber].&[011074], [Measures].[Sale Amount]))
And IsEmpty(([Item].[ItemNumber].&[011069], [Measures].[Sale Amount]))
)
Or IsEmpty([Measures].[Sale Amount]),
0 , 1
)
)
select
{[Measures].[Sale Amount]} on columns,
non empty filter([Customer].[Customer].children, [Measures].[BoughtDispenser])
* {[Item].[ItemNumber].members}
on rows
from [Sales]
where [EnteredDate].[Quarter].&[2010-01-01T00:00:00]
;
The object is to show all the items purchased by customers who also bought either of the two dispensers (011069 and 011074).
I based the calculated member on a query I found to do basket analysis. I feel like there should be a way to write it with the set {[Item].[ItemNumber].&[011074], [Item].[ItemNumber].&[011069]} instead of the two IsEmpty tests. Everything I've tried ended up having every Customer in the result.
My environment is SQL Server Analysis Services 2005.
Yes I can! It just required a slightly different approach to the calculated member:
with member [Measures].[BoughtDispenser] as
Sum(Descendants([Customer].[Customer].CurrentMember, [Customer].[Customer])
* {[Item].[ItemNumber].&[011069], [Item].[ItemNumber].&[011074]},
[Measures].[Quantity Shipped]
)
select
{[Measures].[Sale Amount]} on columns,
non empty filter([Customer].[Customer].children, [Measures].[BoughtDispenser])
* {[Item].[ItemNumber].members}
on rows
from [Sales]
where [EnteredDate].[Quarter].&[2010-01-01T00:00:00]
;