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).
Related
I raised a ticket on grand totals when filtering ages ago and I used the proposed solution yesterday to get one dimension working:
WITH
SET [FilteredSet] AS
{
FILTER([CDR].[CDR].Members,([CDR].[CDR].CURRENTMEMBER.MEMBERVALUE="70648") OR ([CDR].[CDR].CURRENTMEMBER.MEMBERVALUE="70646"))
}
MEMBER [CDR].[CDR].[Test] AS Aggregate([FilteredSet])
SELECT NON EMPTY {[Measures].[CS01.TenorTotal] } ON COLUMNS, NON EMPTY {[FilteredSet], [CDR].[CDR].[Test]} ON ROWS FROM [TraderCube] WHERE ([Date].[Date].[2022-04-01],[Epoch].[Epoch].[Branch].[master].[17])
(Other ticket with useful info)
MDX - Grand total missing when filtering
And as I expand the test query (to get it all working and I then expand the C# code to add it) I note that this works:
WITH
SET [FilteredSet] AS
{
FILTER(CROSSJOIN(HIERARCHIZE(DRILLDOWNLEVEL([CDR].[CDR].[ALL].[AllMember]),POST),HIERARCHIZE(DRILLDOWNLEVEL([Book].[Book].[ALL].[AllMember]),POST)),(LEFT([CDR].[CDR].CURRENTMEMBER.MEMBERVALUE,2)="66") )
}
SELECT NON EMPTY {[Measures].[CS01.TenorTotal] } ON COLUMNS, NON EMPTY {[FilteredSet]} ON ROWS FROM [TraderCube] WHERE ([Date].[Date].[2022-04-01],[Epoch].[Epoch].[Branch].[master].[17])
But we will often filter on the 2nd (or 3rd, 4th etc) dimension, like so and the total (AllMember) is filtered out from Book as it does match the INSTR comparisons.
How do I get my Aggregate MEMBER to work properly here? I've placed [?] in position as I can get this sort of setup to work on one dimension (E.g. [CDR] as shown in first code block) but here the query returns [CDR] and then the [Book] members that match and I want to 'glue' my Agregate MEMBER [?] of the measure as a grand total.
WITH
SET [FilteredSet] AS
{
FILTER(CROSSJOIN(HIERARCHIZE(DRILLDOWNLEVEL([CDR].[CDR].[ALL].[AllMember]),POST),HIERARCHIZE(DRILLDOWNLEVEL([Book].[Book].[ALL].[AllMember]),POST)),(LEFT([CDR].[CDR].CURRENTMEMBER.MEMBERVALUE,2)="66")
AND (INSTR([Book].[Book].CURRENTMEMBER.MEMBERVALUE,"72")>0 OR INSTR([Book].[Book].CURRENTMEMBER.MEMBERVALUE,"73")>0))
}
MEMBER [?] AS Aggregate([FilteredSet])
SELECT NON EMPTY {[Measures].[CS01.TenorTotal] } ON COLUMNS, NON EMPTY {[FilteredSet], [?]} ON ROWS FROM [TraderCube] WHERE ([Date].[Date].[2022-04-01],[Epoch].[Epoch].[Branch].[master].[17])
Current MDX error back is:
'The 2 objects do not have the same dimensionality: [[CDR], [Book]] and [[Measures]]'
Thanks to more advanced MDX-ers out there! :)
Leigh Tilley
TilleyTech Ltd
P.S. Sorry no screenshots...client browser trackers would detect it and I'd get in trouble!
I am facing very strange issue with MDX (SSAS 2014), on which simplest calculated member is taking forever to execute. Could someone please help me to understand why i am facing this issue. If i not use calculated member everything works fast and result comes in seconds. When i remove Producer attribute, query performances well.
Below is the complete query.
WITH
MEMBER Measures.AsOfDate AS ("[Policy Effective Date].[Year-Month].[Date].&[2018-01-04T00:00:00]")
MEMBER Measures.YTDPremium AS AGGREGATE (YTD(STRTOMEMBER(Measures.AsOfDate)), [Measures].[Written Premium])
SELECT NON EMPTY
{
Measures.YTDPremium
} ON COLUMNS, NON EMPTY
{
(
[Program].[Program Name].[Program Name]
,[Insuring Company].[Insuring Company Name].[Insuring Company Name]
,[Line Of Business].[Line Of Business].[Line Of Business]
,[Producer].[Producer Name].[Producer Name]
)
} ON ROWS
FROM [Premium]
Try understand what the following part does in your query
NON EMPTY { ( [Program].[Program Name].[Program Name]
,[Insuring Company].[Insuring Company Name].[Insuring Company Name]
,[Line Of Business].[Line Of Business].[Line Of Business]
,[Producer].[Producer Name].[Producer Name]
) } ON ROWS
In the above MDX you are telling the server to take a cross product of all values of "Programs", "Line Of Business" and "Producer Name". So lets say you have 4 values of programs , 3 values of line of business and 2 values of producer name. The total combinations are 4*3*2=24
Now the "Non empty" removes any combinations that are not present in your dataset. This is done by removing all rows that have "Null" value in column value.
Your measure is returning value irrespective if that combination exists or not. You can modify your Calculatedmeasure to return value only in the case if the combination is valid. This can be achived by checking an actual measure for that combination
Edit: based the below example is based on the comment
In the below example i am trying to get the internet sales amount categories and components
select
{ [Measures].[Internet Sales Amount] }
on columns,
(
[Product].[Category].[Category],
[Customer].[Country].[Country]
)
on rows
from [Adventure Works]
Result
Now add "Non empty" to the query and observe the results.
Results
Now lets add calculted measure that returns "hello". Notice how the non empty clause is ineffective.
Now modify the code make the calculated measure check other measures for null
with member measures.t as
case when [Measures].[Internet Sales Amount] = null then null else "hello" end
select
{ [Measures].[Internet Sales Amount] ,measures.t }
on columns,
non empty
(
[Product].[Category].[Category],
[Customer].[Country].[Country]
)
on rows
from [Adventure Works]
Result
The bottom line: Because of cross product your result is so huge that SSAS is having hard time handling it.
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.
I have the following MDX statement on the $Monitoring cube:
WITH
MEMBER [Measures].[Unique Users] AS distinctcount(([User].[User].[User L].members
, [Measures].[Open Report Count])),format_string="#,#0"
SELECT
NON EMPTY { {[Measures].[Unique Users],[Measures].[Open Report Count]} } ON COLUMNS,
NON EMPTY { [Time].[Time].[Day L] } ON ROWS
FROM ( SELECT
{ lag(strtomember("[Time].[Time].["+right("0"+str(day(SchemaRefreshTime())),2) +"-"+ right("0"+str(month(SchemaRefreshTime())),2) + "-"+str(year(SchemaRefreshTime()))+ "]"), 6):strtomember("[Time].[Time].["+right("0"+str(day(SchemaRefreshTime())),2) +"-"+ right("0"+str(month(SchemaRefreshTime())),2) + "-"+str(year(SchemaRefreshTime()))+ "]") } ON 0 FROM [$Monitoring])
/*ic3navigation*/
axis 1 NON EMPTY order(nonempty(Descendants([Report].[Report], ,leaves),[Open Report Count]),[Open Report Count],desc)
FILTERBY /*ic3*/ {[Time].[Time].[ALL].&[2015].&[2015-11-27].&[27-11-2015]}
FILTERBY /*ic3*/ {[User].[User].[All Users].&[<user>]}
*) change <user> with the actual user name
*) the ...lag.. formula is used to give the last 7 days based on schema refresh time
***) this MDX query can be run on any $Monitoring cube if you have filled in an existing user
I would expect the distinctcount function to take into account the FILTERBY. So the result should be 1 (there is just one user selected). The strange thing is, that it does not. It shows more than one user, so I assume the FILTERBY on users is not taken into account for the distinctcount.
The same thing happens when I move the FILTER BY to the AXIS or to the ROWS or COLUMNS.
Is this a bug or is this something how MDX/ MDX++ works in icCube?
Please advise.
It's the expected behaviour. Welcome to advanced MDX !
A FilterBy is exactly the same as a sub-select.
Members are not filtered by a subselect or a where clause in a calculated members.
In a calculated member, a tuple that defines a hierarchy will 'overwrite' the one defined in a subquery or where clause.
------ UPDATE ------
If you want to filter the set with the where clause/subselect you've the EXISTING operator.
MEMBER [Measures].[Unique Users] AS count( Existing [User].[User].[User L].members),format_string="#,#0"
if you want only users with data for the cell tuple :
MEMBER [Measures].[Unique Users] AS count( nonempty( Existing [User].[User].[User L].members, [Measures].[Open Report Count])),format_string="#,#0"
If you've a large number of users I'd advise adding a measure [Distinct Users] that is a distinct count on the user id. This way you avoid all complexity that we're facing here.
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.