MDX filtering by multiple dimension members - sql

Problem
I need to create a report which will list a number of accounts that match certain criteria - simulationDate, statisticPeriod, region.
Right now my query looks like this:
WITH MEMBER [Measures].[Count] as 1
SELECT [Measures].[Count] ON COLUMNS,
NON EMPTY
Crossjoin(
[Account].[Account Number].ALLMEMBERS,
{[simulationDate].[day].&[10010101]},
{[statisticPeriod].[period].&[201201]},
{[region].[code].&[SO]}
)
ON COLUMNS
FROM [myWH]
Is this cross-dimensional filtering okay?

This is slightly more modern using the * notation instead of the Crossjoin function:
WITH
MEMBER [Measures].[Count] AS 1
SELECT
[Measures].[Count] ON COLUMNS
,NON EMPTY
[Account].[Account Number].ALLMEMBERS*
{[simulationDate].[day].&[10010101]}*
{[statisticPeriod].[period].&[201201]}*
{[region].[code].&[SO]} ON COLUMNS
FROM [myWH];
I'm assuming that your custom measure [Measures].[Count] is just a place-holder?
This table will be very wide if you have that cross-join on COLUMNS but that might just be a typo:
WITH
MEMBER [Measures].[Count] AS 1
SELECT
[Measures].[Count] ON COLUMNS,
NON EMPTY
[Account].[Account Number].ALLMEMBERS*
{[simulationDate].[day].&[10010101]}*
{[statisticPeriod].[period].&[201201]}*
{[region].[code].&[SO]} ON ROWS
FROM [myWH];
You have added the keywords NON EMPTY in front of the rows cross-join. This is telling the processor to exclude any rows that are empty - empty for [Measures].[Count] ....but this measure is never empty it is always equal to 1. So the following without Non Empty should return exactly the same result:
WITH
MEMBER [Measures].[Count] AS 1
SELECT
[Measures].[Count] ON COLUMNS,
[Account].[Account Number].ALLMEMBERS*
{[simulationDate].[day].&[10010101]}*
{[statisticPeriod].[period].&[201201]}*
{[region].[code].&[SO]} ON ROWS
FROM [myWH];
So in terms of filtering you aren't doing any - what sort of filtering do you need? If you replace [Measures].[Count] with an actual measure from your cube and use the NON EMPTY then you should see a lot less rows:
SELECT
[Measures].[ReplaceWithActualMeasure] ON COLUMNS,
NON EMPTY
[Account].[Account Number].ALLMEMBERS*
{[simulationDate].[day].&[10010101]}*
{[statisticPeriod].[period].&[201201]}*
{[region].[code].&[SO]} ON ROWS
FROM [myWH];

In the end I ended up using the filters as my columns, and letting the NON EMPTY clause take care of the filtering:
SELECT
NON EMPTY
{[simulationDate].[day].&[10010101]} *
{[statisticPeriod].[period].&[201201]} *
{[region].[code].&[SO]}
ON COLUMNS,
NON EMPTY
[Account].[Account Number].ALLMEMBERS
ON ROWS
FROM [myWH]

Related

Rewrite the where clause into a Calculated member slicer

could you help me with someting please. I have an MDX query who slice my cube with a Named Set, these results are great, however I need to create a calculated measure and I have not been able to "rewrite" my where clause in the calculated expression.
This MDX works as I need:
select non empty [Measures].[Demanda Real] on 0,
non empty [Agente Distribuidor].[Nombre Distribuidor].[Nombre Distribuidor].members on 1
from Demanda
where [SkSubmercadoUsuario]
I tried to rewrite the above query and it doesn't work:
with member [Measures].[Demanda Real Nueva]
as
([Measures].[Demanda Real],[SkSubmercadoUsuario])
select [Measures].[Demanda Real Nueva] on 0,
non empty [Agente Distribuidor].[Nombre Distribuidor].[Nombre Distribuidor].members on 1
from Demanda
If I am correct, you want your measure "[Measures].[Demanda Real]" to always have a filter named set "[SkSubmercadoUsuario]". I translated your senario to adventure works. First run the create set part alone. Then the next two parts, with first part commented
create SET [Adventure Works].[testSet] AS ([Geography].[State-Province].&[NY]&[US])
Now comment the above part and run
Select [Measures].[Reseller Sales Amount]
on columns,
non empty
[Product].[Product].[Product]
on rows
from [Adventure Works]
where
[testSet]
Now run the third part
with member [Measures].[Test]
as
'('+(settostr([testSet]) ) + ',[Measures].[Reseller Sales Amount])'
Select (strtoset([Measures].[Test]))
on columns,
non empty
[Product].[Product].[Product]
on rows
from [Adventure Works]

Filter dimensions for a specific member in MDX

I need to filter the dimension [Line] just for a specific [Year].Member.
For example,
[Time].[2004] to show results ([Product].[Line].[Classic Cars] and [Product].[Line].[Ships]) - excude the rest of [Product].[Line] members for [Time].[2004] but do not exclude [Product].[Line] members for the other [Time].Members.
I need a code compatible with Mondrian.
Any suggestion?
SELECT
NON EMPTY {[Measures].[Sales]} ON COLUMNS,
NON EMPTY NonEmptyCrossJoin([Time].[Years].Members, [Product].[Line].Members) ON ROWS
FROM
[SteelWheelsSales]
Something like this should work:
SELECT
NON EMPTY
{[Measures].[Sales]} ON COLUMNS
,NON EMPTY
{
(
[Time].[2004]
,{
[Product].[Line].[Classic Cars]
,[Product].[Line].[Ships]
}
)
,NonEmptyCrossJoin
(
Except
(
[Time].[Years].MEMBERS
,[Time].[2004]
)
,[Product].[Line].MEMBERS
)
} ON ROWS
FROM [SteelWheelsSales];

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];

Union in MDX query

In my time dimensions i have 2013,2014,2015.
How can i make a Union in this mdx so i get the results from this mdx for all thoose years and not only for 2014 like in the example..
select NON EMPTY {[Measures].[Absatz Plan], [Measures].[Umsatz Plan], [Measures].[Absatz Effektiv], [Measures].[Umsatz Effektiv]} ON COLUMNS,
NON EMPTY Crossjoin(Hierarchize({([Time].[2014], [Artikel].[All Artikels], [Markt].[All Markts])}), {[Version].[14], [Version].[16], [Version].[18]}) ON ROWS
from [Budget]
Just apply CrossJoin twice:
select NON EMPTY
{[Measures].[Absatz Plan], [Measures].[Umsatz Plan], [Measures].[Absatz Effektiv], [Measures].[Umsatz Effektiv]}
ON COLUMNS,
NON EMPTY
CrossJoin(
Crossjoin(
{[Time].[2013], [Time].[2014], [Time].[2015]},
{([Artikel].[All Artikels], [Markt].[All Markts])}
),
{[Version].[14], [Version].[16], [Version].[18]}
)
ON ROWS
from [Budget]
I removed the Hierarchize, as I think it is not necessary in this context. It would order its argument by the order defined for the hierarchy in the cube. If the order of the result seems wrong, you could re-add it.

Getting a count of users each day in Mondrian MDX

I'm trying to write a query to give me the total number of users for each customer per day.
Here is what I have so far, which for each customer/day combination is giving the total number of user dimension entries without splitting them up by customer/day.
WITH MEMBER [Measures].[MyUserCount]
AS COUNT(Descendants([User].CurrentMember, [User].[User Name]), INCLUDEEMPTY)
SELECT
NON EMPTY CrossJoin([Date].[Date].Members, [Customer].[Customer Name].Members) ON ROWS,
{[Measures].[MyUserCount]} on COLUMNS
FROM
[Users]
The problem with your calculated member is that [User].CurrentMember is set to the All member for every row tuple, and thus the count is the total. What you need is a way for the [Customer].CurrentMember and [Date].CurrentMember to effectively filter the [User] dimension.
You need to use a measure that makes sense, i.e. that will have a non-empty value for meaningful joins of the dimension members that you're interested in.
To find this out, you could start by running a query like this:
SELECT
NON EMPTY CrossJoin(
[User].[User Name].Members,
[Measures].[Some measuse]
) ON COLUMNS,
NON EMPTY CrossJoin(
[Date].[Date].Members,
[Customer].[Customer Name].Members
) ON ROWS
FROM [Project]
You would have selected Some measure adequately. The results of that query will be a lot of empty cells, but in a given row, the columns that do have a value correspond to the Users that are related to a given Customer x Date tuple (on the row). You want to count those columns for every row. COUNT and FILTER are what you need, then the query with the calculated member will be
WITH MEMBER [Measures].[User count] AS
COUNT(
FILTER(
[User].[User Name].Members,
NOT ISEMPTY([Measures].[Some measure])
)
)
SELECT
NON EMPTY {[Measures].[User count]} ON COLUMNS,
NON EMPTY CrossJoin(
[Date].[Date].Members,
[Customer].[Customer Name].Members
) ON ROWS
FROM [Users]
I am assuming a fair bit here, but with some experimentation you should be able to work it out.