MDX on multiple hierarchical dimensions - ssas

2 hierarchical dimensions (for location and time) are defined on a cube. My question is about possibility of writing a single MDX query for retrieving following structure. I mean writing a single query for obtaining values V1, V2, V3 and V4:
The obvious way is to use multiple MDX queries. Just wondering if there is some magic syntax in MDX.

Try:
SELECT
{
[Measures].[Some Measure]
} ON 0,
{
[Location].[Level 1].[Level 1].Members*
[Date].[Year].[Year].Members*
[Location].[Level 2].[Level 2].Members
} ON 1
FROM [Your Cube]
You can also get the totals with:
SELECT
{
[Measures].[Some Measure]
} ON 0,
{
[Location].[Level 1].Members*
[Date].[Year].Members*
[Location].[Level 2].[Level 2].Members
} ON 1
FROM [Your Cube]
No magic here - just crossjoining the attribute hierarchies as needed. Please note that if you place the two Location hierarchies next to each other the excution will be faster.
No idea if this completely answers your question but at least may help a bit...

Related

MDXQuery - Currentmember with his parent

I'm trying to write a MDX query that would display all my products and the subgroups (hierarchy parent) that they belong to. While the task seems rather trivial i still can't figure it out. Here is my MDX query.
select
{
[Products].[Hierarchy].currentmember.parent
}
on 0,
{
[Products].[Hierarchy].[Product].members
}
on 1
from [CUBE]
I also tried
select
{
Ancestor([Products].[Hierarchy].currentmember,
[Products].[Hierarchy].[Subgroup])
}
on 0,
{
[Products].[Hierarchy].[Product].members
}
on 1
from [CUBE];
But all I get from it is a gray list of products without any actual column. Any help/tips would be greatly appreciated.
If you want to use the same hierarchy then you can only use it on one axis - there are 3 axis in context - ON COLUMNS / ON ROWS / WHERE.
So putting [Products].[Hierarchy]. ON COLUMNS and also ON ROWS would throw an exception.
What you can do is move some of the logic into a WITH clause and move the narrative into the Measures dimension:
WITH
MEMBER [Measures].[ProdName] AS
Ancestor(
[Products].[Hierarchy].currentmember,
[Products].[Hierarchy].[Subgroup]
).MEMBER_CAPTION
SELECT
[Measures].[ProdName] ON 0,
[Products].[Hierarchy].[Product].MEMBERS ON 1
FROM [CUBE];
You could make use of your attribute hierarchies and do something like this:
SELECT
{} ON 0,
[Products].[Product].[Product]
*[Products].[Subgroup].[Subgroup]
ON 1
FROM [CUBE];

Easiest way to programmatically generate MDX rowcount query?

Right now I'm dealing with a program that can generate and return SQL or MDX queries (depending on the source database of the queries). I'm working on adding a feature that counts all the rows returned by a given query.
Now, I have some small background with SQL, so I was able to parse table names and generate a rowcount. However, MDX is a completely new beast for me.
In SQL, I'm creating:
SELECT
COUNT(SUM)
AS ROWS
FROM
(
COUNT(*) AS COUNT FROM TABLE1
UNION ALL
COUNT(*) AS COUNT FROM TABLE2
UNION ALL
COUNT(*) AS COUNT FROM TABLE3
ETC...
)
Now, what I'm wondering is, how would I do something similar with MDX? I've done some reading on MDX, and from what I gathered the basic notation is
[Dimension].[Hierarchy].[Level]
Now with SQL, I parsed the table names out of a larger generated query and simply inserted them into a new programmatically generated query. What would I have to grab from a larger MDX query to generate my own rowcounting query and sending it off to run? A simpler example of the MDX I'm dealing with would be:
WITH
MEMBER [BUSINESS1].[XQE_RS_CM1] AS '([BUSINESS1].[COMPANY_H].[all])', SOLVE_ORDER = 8
MEMBER [BUSINESS2].[XQE_RS_CM0] AS '([BUSINESS2].[all])', SOLVE_ORDER = 4
SELECT
NON EMPTY {[BUSINESS2].[ALL_TIME_H].[CALENDAR_YEAR_L].MEMBERS AS [XQE_SA1] , HEAD({[BUSINESS2].[XQE_RS_CM0]}, COUNT(HEAD([XQE_SA1]), INCLUDEEMPTY))} DIMENSION PROPERTIES PARENT_LEVEL, PARENT_UNIQUE_NAME ON AXIS(0),
NON EMPTY {[BUSINESS1].[COMPANY_H].[COMPANY_CD__L].MEMBERS AS [XQE_SA0] , HEAD({[BUSINESS1].[XQE_RS_CM1]}, COUNT(HEAD([XQE_SA0]), INCLUDEEMPTY))} DIMENSION PROPERTIES PARENT_LEVEL, PARENT_UNIQUE_NAME ON AXIS(1),
NON EMPTY {[Measures].[Measures].[BUSINESS3]} DIMENSION PROPERTIES PARENT_LEVEL, PARENT_UNIQUE_NAME ON AXIS(2)
FROM
[SOURCE] CELL PROPERTIES CELL_ORDINAL, FORMAT_STRING, VALUE
Any insight would be awesome, thanks.
At first glance your script looks reasonable then after unravelling it becomes a bit(!) more complex.
The main difference between this and other scripts is its use of axis(2). In a sub-select extra dimensions are often used but this is a little odd as most clients can't handle 3 dimensional cellsets - so I'm intrigued by what is consuming this info?
Also the member [BUSINESS1].[XQE_RS_CM1] is a single member as is [BUSINESS2].[XQE_RS_CM0] so what is the point of the sections HEAD... ?
WITH
MEMBER [BUSINESS1].[XQE_RS_CM1] AS
([BUSINESS1].[COMPANY_H].[all]), SOLVE_ORDER = 8
MEMBER [BUSINESS2].[XQE_RS_CM0] AS
([BUSINESS2].[all]), SOLVE_ORDER = 4
SELECT
NON EMPTY
{[BUSINESS2].[ALL_TIME_H].[CALENDAR_YEAR_L].MEMBERS AS [XQE_SA1]
,HEAD(
{[BUSINESS2].[XQE_RS_CM0]},
COUNT(
HEAD([XQE_SA1])
,INCLUDEEMPTY
)
)}
ON AXIS(0),
NON EMPTY
{[BUSINESS1].[COMPANY_H].[COMPANY_CD__L].MEMBERS AS [XQE_SA0]
,HEAD(
{[BUSINESS1].[XQE_RS_CM1]},
COUNT(
HEAD([XQE_SA0])
,INCLUDEEMPTY
)
)}
ON AXIS(1),
NON EMPTY
{
[Measures].[Measures].[BUSINESS3]
}
ON AXIS(2)
FROM
[SOURCE]
Does the following return the same data as the original script?
SELECT
NON EMPTY
{
[BUSINESS2].[ALL_TIME_H].[CALENDAR_YEAR_L].MEMBERS
,[BUSINESS2].[all]
}
ON 0,
NON EMPTY
{
[BUSINESS1].[COMPANY_H].[COMPANY_CD__L].MEMBERS
,[BUSINESS1].[COMPANY_H].[all]
}
ON 1
FROM [SOURCE]
WHERE [Measures].[Measures].[BUSINESS3];
All you need to calculate then is the count of members returned in the following set on the rows:
{
[BUSINESS1].[COMPANY_H].[COMPANY_CD__L].MEMBERS
,[BUSINESS1].[COMPANY_H].[all]
}

MDX - Why Cross join between measures do not work?

In MDX, we can CROSS JOIN two members, a measure and a member but not two measures. Why is this so? What does it imply?
SELECT
[Measures].[xyz] * [DimTable1].[SomeHierarchy].[Level] on 0,
[DimTable2].[SomeOtherHierarchy].&[Value] on 1
FROM [MyCube]
// WORKS
SELECT
[Measures].[xyz] on 0,
[DimTable2].[SomeOtherHierarchy].&[Value] * [DimTable1].[SomeHierarchy].[Level] on 1
FROM [MyCube]
// OF COURSE IT WORKS
SELECT
[Measures].[xyz] * [Measures].[ABC] on 0,
[DimTable1].[SomeHierarchy].&[Value] on 1
FROM [MyCube]
// DOES NOT WORK!!
I believe you forgot:
SELECT
[dd].[hh].[mm1] * [dd].[hh].[mm2] on 0,
[DimTable1].[SomeHierarchy].&[Value] on 1 FROM [MyCube]
did not work neither. [Measures] is not different than [dd] in my example. In MDX you cannot define a tuple with _ several members _ of the _ same hierarchy _. Have a look to this gentle introduction explaining the main concepts.
EDIT
Your third query, that does not work, looks like this:
The yellow area is empty so it is understandable that it is not happy.
EDIT
Following is an analogy using Excel pivot tables which use OLAP technology
If you put a crossjoin of measures A and B on rows you get something like this:
Then if we add a very small level (with 4 members) onto columns we get the following:
So what will go into the main body of this table?
A count is possible and probably is, in MDX, if you create a custom measure (don't have a server to test this statement on). Excel will default to a count but the result is pretty pointless?

MDX date range query with a missing boundry date

I need an MDX query for Mondrian filtered by date, where one or both of the boundry dates may not exist. I'm using the query below that works as long as both 2013-01-01 and 2013-01-08 dimensions exist. If one of the two dates does not exist then it returns no results, even though the dimensions in between do exist. How would I get this query to work even in the case of a missing boundry date dimension?
SELECT
NON EMPTY {Hierarchize({[Measures].[Number of Something]})} ON COLUMNS,
NON EMPTY {[Date].[2013-01-01]:[Date].[2013-01-08]} ON ROWS
FROM [Users]
MDX is built with the assumption that every member that you refer to exists; it is best then to make sure all conceivable date dimension members do exist by having a separate table with these values precomputed.
You could get tricky and implement that table as a stored procedure but date dimensions don't take up a lot of space in the grand scheme of things so you'd hardly ever do this.
I don't know of any other way to solve your problem.
try to eliminate the NON EMPTY
Even I haven't yet understand the reason of implementing this logic, you can hide this by adding . If you add custom member in Mondrian try it.
/* Exclude Missing Member */
Create Set CurrentCube.[MissingMemberSet] As
iif(IsError(StrToMember("[Dimension].[Hierarchy].&[MEMBER]")),
{}, {[Dimension].[Hierarchy].&[MEMBER]});
Create Member CurrentCube.Measures.[Calculation on Missing Member]
AS
IIF ([MissingMemberSet].Count > 0,
([Dimension].[Hierarchy].&[MEMBER],Measures.[X Measure]),
0
)
,
FORMAT_STRING = "Currency",
LANGUAGE = 1033,
NON_EMPTY_BEHAVIOR = { [X Measure] },
VISIBLE = 1 , DISPLAY_FOLDER = 'Display Folder' ;
Also you can implement in using IIF(IsError or IIF(Exists MDX functions.

An simple mdx error, unknown-member measures.unit_name used in query

We are using hyperion, but this simeple mdx caused the error:"unknown-member measures.unit_name used in query".
why? Is "Measures" available in hyperion? Or do we need enable it?
Please help.
WITH MEMBER [Measures].[Unit_Name] AS '[Organization].currentmember.member_name'
SELECT {
[Measures].[Unit_Name]
} on columns,
{
[organization].[40-00012].members
} on rows from OPEXDSH3.OPEXDSH3
I suppose you want to retrieve the Organizatios catalog,
Did you try using DIMENSION PROPERTIES syntax?
Select
{[Measures].DefaultMember} On Columns,
{[organization].[40-00012].members} DIMENSION PROPERTIES MEMBER_NAME, MEMBER_KEY On Rows
From OPEXDSH3.OPEXDSH3