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.
Related
I'm using SSAS 2019 and have the following MDX query to determine data errors - i.e. in this case where a given score ([Measures].[Score]) is above what the maximum score ([PerformanceLevel].[MaxScore]) is
SELECT NON EMPTY {
[Measures].[FactTestScoreCount]
} ON COLUMNS,
NON EMPTY
{(
[TestEvent].[Key].[Key].Members
)} ON ROWS
FROM [TestScore]
WHERE
(
FILTER(
[PerformanceLevel].[MaxScore].[MaxScore].Members,
[PerformanceLevel].[MaxScore].CurrentMember.MemberValue < [Measures].[Score]
)
)
...you'll note it uses a Measure value to compare against a Dimension value in the filter
However the above query incorrectly returns all rows (it should return zero rows as we have no scores in the current database that are above the maximum score)
I have tried using a HAVING and also tried to add the filter into the FROM however I get the same result. I have also tried converting the data-type to int on both sides of the expression but to no avail. I tried temporarily changing the condition to hard-code (numeric) values and this seems to narrow down the issue as being the [Measures].[Score] in the FILTER - i.e. as far as I can see putting the Measure within the FILTER doesn't seem to be working as expected but I can't work out why
Any ideas would be much appreciated
I didn't fully understand what the first parameter of the Filter function represented - specifically the granularity, otherwise it (depending on your aggregation type will SUM the measure). Also moving the Filter up to the select allows more flexibility when joining/displaying rows - so I came up with the below which works well
SELECT NON EMPTY {
[Measures].[FactTestScoreCount]
} ON COLUMNS,
Filter(
NonEmpty(
{(
[TestEvent].[Key].[Key].members
)}
), [Measures].[Score] > [PerformanceLevel.[MaxScore].CurrentMember.MemberValue
) ON ROWS
FROM [TestScore]
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 :)
When I run this mdx query, works fine (get the children members from a hierarchy level):
select {} on columns,
[Dimension].[hierarchy].[level].children on rows
from [Cube]
But, when I add some tuple on rows, doesn't filter filter the children members (shows all the members) :S
select {} on columns,
[Dimension].[hierarchy].[level].children
* [Dimension2].[hierarchy2].[level2].allmembers on rows
from [Cube]
* is a cross join - you will get the Cartesian product of [Dimension].[hierarchy].[level].children and [Dimension2].[hierarchy2].[level2].allmembers because they are different dimensions.
If they were two hierarchies from the same dimension then auto exist behaviour would limit the results e.g. Year2014 crossed with month should just show the months in 2014.
Try using DESCENDANTS function + you might not require NULLs so try the NON EMPTY
SELECT
{} ON COLUMNS,
NON EMPTY
DESCENDANTS(
[Dimension].[hierarchy].[level].[PickAHigherUpMember],
[Dimension].[hierarchy].[PickTheLevelYouWantToDrillTo]
)
*
[Dimension2].[hierarchy2].[level2].allmembers ON ROWS
FROM [Cube]
if you look at the mdx language reference for children, you will also find another example of how to use the function with a hierarchy in stead of a member_expression.
http://msdn.microsoft.com/en-us/library/ms146018.aspx
but it won't work with a hierarchy level.
Maybe the row expression was initialy a hierarchy that you've have changed into a level expression.
in the following a similar working mdx with a hierarchy on rows:
select {} on 0,
[Product].[Model Name].children
*
[Geography].[Country].[All Geographies]
on 1
FROM [Adventure Works
Philip,
I guess you want only those rows where the children have a value on the default measure. In that case you could try the following:
select {} on columns,
Nonempty([Dimension].[hierarchy].[level].children
* [Dimension2].[hierarchy2].[level2].allmembers) on rows
from [Cube]
Now if, for the children, you'd need all the members from Dimension2 then you could try:
select {} on columns,
Nonempty([Dimension].[hierarchy].[level].children, [Dimension2].[hierarchy2].[level2].allmembers)
* [Dimension2].[hierarchy2].[level2].allmembers) on rows
from [Cube]
In the second case the Nonempty function takes a second parameter and the cross join is done with the result of the Nonempty function. For the documentation on Nonempty including the usage of the second parameter see https://learn.microsoft.com/en-us/sql/mdx/nonempty-mdx
Here is the query that I am using:
SELECT
NON EMPTY { [Dim Date].[Week].[Week].Members } ON COLUMNS,
[Dim Source].[Source Name].[Source Name].Members ON ROWS
FROM [Some Cube];
The things is, right now, I have many measures.
But as I am using dimension members on COLUMNS, I cannot indicate the measure anymore.
So this query results in a default measure.
My question is how can I indicate the measure instead of using the default in mdx query?
Or is there any other way that I can do this query (dimension in both row and columns is required for reading result logic in C# in possible) ?
You can do it in two ways:
Either on the SELECT statement, as
{ [Dim Date].[Week].[Week].Members } * { [Measures].[My Measure] } ON COLUMNS,
or on the WHERE slicer by adding
WHERE [Measures].[My Measure]
at the end.
I've faced a issue with MDX query, that I don't know how to workaround. I have following query:
SELECT
{
[Measures].[Cost],
[Measures].[Non additive]
} ON COLUMNS,
NON EMPTY
{
[Organization].[Organization Name].[Organization Name].MEMBERS
*[Time].[Month].[Month].MEMBERS
*[Region].[City].[City].MEMBERS
} ON ROWS
FROM [Cube]
And I would like to display "[Measures].[Non additive]" not at the lowest grouping level, but at the Organization Level. Is it possible?
Thanks for any help.
When I have a measure I don't walways want to display, I make a copy of it and include a test for the level of the current cell.
WITH MEMBER [Measures].[My New Measure Name]
AS 'IIF(IsLeaf([Organization].currentMember), NULL, [Measures].[Non additive])'
SELECT
{
[Measures].[Cost],
[Measures].[My New Measure Name]
} ON COLUMNS,
NON EMPTY
{
[Organization].[Organization Name].[Organization Name].MEMBERS
*[Time].[Month].[Month].MEMBERS
*[Region].[City].[City].MEMBERS
} ON ROWS
FROM [Cube]
The new measure tests whether the Organisation member is at the leaf level (the bottom of the hierarchy). If so it returns blank. If not, it returns the value of the old measure.
If you want more control, test if [Organisation].level = [Organisation].levels(1) and vary the number to detect which level you want (lower levels are higher numbers).