mdx calculated measure versus measure - mdx

just wondering if you could explain to me why these two mdx statements yield different results, and how I would alter the calculated measure to be correct. I am assuming the calculated measure is incorrectly using the sum function.
SELECT
{
[Measures].[PPPH]
}
ON COLUMNS,
{
[Matter].[Parent Matter Lawyer - Responsible].&[qnas]
}
ON ROWS
FROM [Expert Hypercube]
WHERE
(
[Date].[Fiscal].[Month].&[201702],
[Relative Period].[Relative Period].&[YTD]
)
versus
with
member measures.[PPPHx] as
sum({{linkmember([Timekeeper].[Person].currentmember,[Matter].[Parent Matter Lawyer - Responsible])}},measures.[PPPH])
select
{
measures.[PPPHx]
} on columns,
{
[Timekeeper].[Person].&[qnas]
} on rows
from [Expert Hypercube]
where
(
[Date].[Fiscal].[Month].&[201702],
[Relative Period].[Relative Period].&[YTD]
)

It's unclear why do you use Sum function at all. LinkMember function returns a member, no need to cover it with {...} like a set. Also you need to use the All member, since it returns [Timekeeper].[Person].CurrentMember + LinkMember([Timekeeper].[Person].CurrentMember,[Matter].[Parent Matter Lawyer - Responsible]).
With
Member [Measures].[PPPHx] as
(
LinkMember([Timekeeper].[Person].CurrentMember,[Matter].[Parent Matter Lawyer - Responsible]),
[Timekeeper].[Person].[All],
[Measures].[PPPH]
)
See a Richard Lees's article about it.

Related

MDX Calculated Member Performance Issue

SELECT NON EMPTY {
[Measures].[Production_Volume]
} ON COLUMNS,
NON EMPTY { (
[Make].[Make ID].[Make ID].ALLMEMBERS
* [Model].[Model Hierarchy].[MDL].ALLMEMBERS
* [Customer].[Customer ID].[Customer ID].ALLMEMBERS
) } ON ROWS
FROM [Model_Cube]
This query is taking 10 min
[Measures].[Production_Volume] is a calculated member in the cube, if I put the definition of this member directly in the query it's taking much lesser time.
WITH MEMBER [Measures].[Production_Volume] AS
([Measures].[Model Count],
([Status].[Status Type].&[T]
,[Mode].[Mode Type].&[A])
)
+ Sum(
([HYBRID_MODELS]
,[Status].[Status Type].&[C]
,[Mode].[Mode Type].&[A])
,[Measures].[Model Count]
)
SELECT NON EMPTY {
[Measures].[Production_Volume]
} ON COLUMNS,
NON EMPTY { (
[Make].[Make ID].[Make ID].ALLMEMBERS
* [Model].[Model Hierarchy].[MDL].ALLMEMBERS
* [Customer].[Customer ID].[Customer ID].ALLMEMBERS
) } ON ROWS
FROM [Model_Cube]
this query is taking 4 sec
Unable to understand the difference between the two, I ran the profiler but couldn't find any difference, except that the first query showed flight recorder snapshot events second query didn't.
The problem was how I created named sets "[HYBRID_MODELS]". I changed them from DYNAMIC to STATIC this helped. Another change I did was replace -{} with the EXCEPT() function. These both changes reduced query time from 30min to 1min!
Hope this helps someone in need :)

Aggregation on different level of dimension hierarchy

I have two dimensions, lets say Date Hierarchy and Product and a measure which has MAX (Measures.[Max]) aggregation.
The requirement would be to have SUM of Measures.[Max] on DAY or HOUR level of Date Hierarchy and be summarized in Month level.
I have the following query:
With
Member Measures.SumOfMax as SUM([Date].[Hierarchy].[Hour].AllMembers, Measures.[Max])
Select
NON Empty
{
Measures.SumOfMax
} ON COLUMNS,
NON EMPTY
{
[Date].[Hierarchy].[Month].AllMembers *
[Product].[Product Name].[Product Name].Allmembers
} Having Measures.[Max] > 0
ON ROWS
FROM [Cube]
Above query runs very slow. Are there any ways to optimized this?
The problem with this query is that the calculated measure Measures.SumOfMax is evaluated for every cell on the axis although it's yielding the same value each time. SSAS engine is not intelligent enough to understand that, but since you know about this behavior, you can take advantage of FE caching so that it gets evaluated only once and gets cached in FE cache. Read more on it here
With
Member Measures.[_SumOfMax] as SUM([Date].[Hierarchy].[Hour].AllMembers, Measures.[Max])
Member Measures.[SumOfMax] as ([Date].[Hierarchy].[Hour].[All], Measures.[_SumOfMax])
Select
NON Empty
{
Measures.SumOfMax
} ON COLUMNS,
NON EMPTY
{
[Date].[Hierarchy].[Month].AllMembers *
[Product].[Product Name].[Product Name].Allmembers
} Having Measures.[Max] > 0
ON ROWS
FROM [Cube]
Hope this helps.

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 Query - return a member contained in the filter

I have an MDX query that is filtering on a particular member, but I need it to return the actual member value as well.
For example:
SELECT NON EMPTY { [Measures].[__No measures defined] } ON COLUMNS, NON EMPTY { ([Archive].[SiteId].[SteId] }ON ROWS FROM [Model] WHERE ( {[Archive].[SiteId].&[{e7672ff4-7f0c-4806-8453-744a17bde4ca}],[Archive].[SiteId].&[{bb7d8f41-c88a-4bcb-ade8-d0533190185a}],[Archive].[SiteId].&[{04cd27b6-e239-4d27-bc58-27f0a8733193}]} )
so in SQL it would basically be -
Select SiteId from Model where SiteId In .....
However this won't work because it says the SiteId Member is already contained in the filter and so appear twice in the query!
So how can filter on SiteId AND return the SiteId?
Thanks!
I decided to use DAX instead. In fact DAX enabled me to perform some better manipulation given my data that sped up the overall application.

Can I Select a Calculated Member On the "Row" Dimension in MDX?

I know I can do this (quick example off the top of my head):
WITH
Member Measures.AnotherDataColumn AS [MyDimension].CurrentMember.Properties("MyProperty")
SELECT
{
Measures.DataColumn,
Measures.AnotherDataColumn
} ON COLUMNS
{
[MyDimension].Item
} ON ROWS
But is there a way to include that same calculated member Measures.AnotherDataColumn in the ROWS dimension?
Thanks in advance!!
You can create calculated members in any dimension, not just the measures dimension, but then you need to tell SSAS how you want it to aggregate the measures. Typically this is aggregating a set of other members from the same dimension and you see something like the following using the Aggregate function:
WITH
Member MyDimension.CalcMember AS Aggregate({[MyDimension].Item1:[MyDimension].Item3})
SELECT
{
Measures.DataColumn,
} ON COLUMNS
{
[MyDimension].Item
} ON ROWS