MDX Get a TopCount over multiple dimensions and add a rest/remainder (icCube) - mdx

I would like to create a TopCount over multiple dimensions, and include a "rest"/"remainder" and a sub-total.
I use the following MDX on the default Sales schema in icCube:
with
member [Product].[Product].[All Products].[rest] as "All Products - top 2"
SET [top] AS
Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
TopCount( s1.CurrentMember * [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) + s1.CurrentMember * {[Product].[Product].[All Products].[rest] , [Product].[Product].[All Products]} )
select
[Measures].[Amount] on 0
[top] on rows
from sales
The result is in the following picture.
How to get a value for "rest"? Using the formula: "All Products" -/- the Top 2

The answer will depend on whether the dimension includes many-to-many relations or not.
If there are no many-to-many, you can either use the SubCubeComplement function:
MEMBER [Product].[Product].[All Products].[rest] as Eval( SubCubeComplement( TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]) ) , [Product].[Product].defaultMember )
or calculate it (all minus the sum of the TopCount set):
MEMBER [Product].[Product].[All Products].[rest] as ([Product].[Product].defaultMember) - Sum( TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]), [Product].[Product].currentMember )
The risk here is that in case you have many-to-many relations, the two solutions above can be subtracting unwanted rows (as they may contain articles that should have been in the final set.)
Therefore, if you have many-to-many relations use the Eval function with the following syntax:
MEMBER [Product].[Product].[All Products].[rest] as Eval( [Product].[Product].[Article].Members - TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]), [Product].[Product].defaultMember )
The statement will therefore be (please note the adjustment on the [top] set definition):
with
// v1 (no many-to-many) - behaves like a FILTERBY
// MEMBER [Product].[Product].[All Products].[rest] as Eval( SubCubeComplement( TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]) ) , [Product].[Product].defaultMember )
//v2 (no many-to-many)
// MEMBER [Product].[Product].[All Products].[rest] as ([Product].[Product].defaultMember) - Sum( TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]), [Product].[Product].currentMember )
//v3 (many-to-many)
MEMBER [Product].[Product].[All Products].[rest] as Eval( [Product].[Product].[Article].Members - TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]), [Product].[Product].defaultMember )
SET [top] AS
Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
s1.CurrentMember * TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) + s1.CurrentMember * {[Product].[Product].[All Products].[rest] , [Product].[Product].[All Products]} )
select
[Measures].[Amount] on 0
[top] on rows
from sales
Version 3 will also work if there are no many-to-many relations.

After some time puzzling I found the solution.
The solution is a combination of icCube's MDX++ functions, namely SubCubeMinus in combination with the category member.
Here's the answer:
with
SET [top 2] as
Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
TopCount( s1.CurrentMember * [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) )
category calculated member [Product].[Product].[All Products].[rest] as subcubeminus(([Customers].[Geography].[All Regions] , [Time].[Calendar].[2010], [Product].[Product].[All Products]) , [top 2])
SET [top 2] as
Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
TopCount( s1.CurrentMember * [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) )
SET [tuples_top2_rest_total] AS
Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
TopCount( s1.CurrentMember * [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) + s1.CurrentMember * {[Product].[Product].[All Products].[rest] , [Product].[Product].[All Products]} )
select
[Measures].[Amount] on 0
[tuples_top2_rest_total] on rows
from sales
Result
Explanation
Create the Top 2 using the Generate function;
Create the calculated category member "rest" (ie others) all the data in the cube for Total Region, 2010 and Total Product MINUS the TOP 2 per combination for region and 2010.

Related

format_string is not working SSAS

WITH MEMBER [Measures].[WagesToSales] as ([Measures].[Value - Fact Wages]/(([Measures].[Value]) - ([Measures].[Sales]))), FORMAT_STRING= '0.00'
SELECT [Measures].[WagesToSales] ON COLUMNS, NON EMPTY { ([Dim Date].[Date Key].[Date Key].ALLMEMBERS * [Dim Store Type].[Store Type].[Store Type].ALLMEMBERS ) } ON ROWS FROM ( SELECT ( Filter( [Dim Location].[Location Name].[Location Name].ALLMEMBERS, Instr( [Dim Location].[Location Name].currentmember.Properties( 'Member_Caption' ), 'BOSTON' ) > 0 ) ) ON COLUMNS FROM ( SELECT ( { [Dim Store Type].[Store Type].&[Boston] } ) ON COLUMNS FROM [People Dashboard 1]))
result still not displaying two decimals.
is there something that i missing?
You Try:
change
FORMAT_STRING= '0.00'
to
FORMAT_STRING='##0.00'
Try the following:
WITH
MEMBER [Measures].[WagesToSales] as
DIVIDE(
[Measures].[Value - Fact Wages]
,[Measures].[Value] - [Measures].[Sales]
)
, FORMAT_STRING= "0.00"
SELECT
[Measures].[WagesToSales] ON 0
, NON EMPTY
[Dim Date].[Date Key].[Date Key].ALLMEMBERS
* [Dim Store Type].[Store Type].[Store Type].ALLMEMBERS
ON 1
FROM
(
SELECT
Filter(
[Dim Location].[Location Name].[Location Name].ALLMEMBERS
, Instr(
[Dim Location].[Location Name].currentmember.Properties( 'Member_Caption' )
, 'BOSTON'
) > 0
)
ON 0
FROM
(
SELECT
[Dim Store Type].[Store Type].&[Boston] ON 0
FROM [People Dashboard 1]
)
);

How to format value as float with 2 deciaml only in mdx?

Here is my value :
VALUE -0,00398911382022891
and member which count this value
MEMBER [Date].[Percentage] AS
([Date].[AverageSaleNumberThisYear] - [Date].[AverageSaleNumberPreviouseYear] )/ [Date].[AverageSaleNumberThisYear].
If I use FORMAT_STRING = "Percent" I am getting this value : -0,40%, but i want exactly the same but without the % sign.
You can use custom format strings in MDX. It sounds like you want
FORMAT_STRING = "0.00"
or
FORMAT_STRING = "Fixed"
I'm assuming that you didn't really want to multiple the value by 100, which is what "Percent" does)
If you do want it multiplied by 100, then do that in the expression:
MEMBER [Date].[Percentage] AS
100 * ([Date].[AverageSaleNumberThisYear] - [Date].[AverageSaleNumberPreviouseYear] ) / [Date].[AverageSaleNumberThisYear].
Try the technique used in z:
WITH
MEMBER [Measures].[x] AS
-0.003989113
,FORMAT_STRING = "Fixed"
MEMBER [Measures].[y] AS
-0.003989113
,FORMAT_STRING = "0.00"
MEMBER [Measures].[z] AS
Round(-0.003989113*100,2)
SELECT
{
[Measures].[x]
,[Measures].[y]
,[Measures].[z]
} ON 0
FROM [AdventureWorks];

In MDX, What is the best way to display the member_key of all dimension members?

In the following example, how can I use the "member_key" for displaying the [Ad Name Dim].[Ad Name].[Name].ALLMEMBERS? in other words, to display ALL ads unique IDs instead of it's names ?
WITH
SET [Selected Measures] AS
{
[Measures].[Cost]
,[Measures].[Clicks]
}
MEMBER [Measures].[MinDate] AS
Head
(
NonEmpty
(
[Time Dim].[Time Dim].[Month] //<<to return minimum month but could be changed to a different level
,(
[Selected Measures]
,[Ad Name Dim].[Ad Name].CurrentMember
)
)
,1
).Item(0).Item(0).Member_Caption
SELECT
{
[Selected Measures]
,[Measures].[MinDate]
} ON COLUMNS
,NonEmpty
(
(
[Ad Name Dim].[Ad Name].[Name].ALLMEMBERS
,
ClosingPeriod
(
[Time Dim].[Time Dim].[Month]
,[Time Dim].[Time Dim].[All Time]
).Lag(3)
:
ClosingPeriod
(
[Time Dim].[Time Dim].[Month]
,[Time Dim].[Time Dim].[All Time]
)
)
) ON ROWS
FROM [CubeName];
Reference: http://bisherryli.com/2012/05/07/mdx-6-use-unique_name-or-member_key-member-property/
Hopefully this helps:
WITH
SET [Selected Measures] AS
{
[Measures].[Cost]
,[Measures].[Clicks]
}
MEMBER [Measures].[MinDate] AS
Head
(
NonEmpty
(
[Time Dim].[Time Dim].[Month] //<<to return minimum month but could be changed to a different level
,(
[Selected Measures]
,[Ad Name Dim].[Ad Name].CurrentMember
)
)
,1
).Item(0).Item(0).Member_Caption
MEMBER [Measures].[MemberKey] AS
[Ad Name Dim].[Ad Name].currentmember.member_key
SELECT
{
[Measures].[MemberKey]
,[Selected Measures]
,[Measures].[MinDate]
} ON COLUMNS
,NonEmpty
(
(
[Ad Name Dim].[Ad Name].[Name].ALLMEMBERS
,
ClosingPeriod
(
[Time Dim].[Time Dim].[Month]
,[Time Dim].[Time Dim].[All Time]
).Lag(3)
:
ClosingPeriod
(
[Time Dim].[Time Dim].[Month]
,[Time Dim].[Time Dim].[All Time]
)
)
) ON ROWS
FROM [CubeName];

SQL SSAS Calculated Member showing #NUM! in Cube?

I have 3 calculated members defined in my SQL Server 2008 SSAS Cube..
CALCULATE;
/* Calculate Sales Volume */
CREATE MEMBER CURRENTCUBE.[Measures].[Ship Volume]
AS [Measures].[QTY SHIPPED] + [Measures].[QTY ADJUST],
FORMAT_STRING = "Standard",
NON_EMPTY_BEHAVIOR = { [QTY SHIPPED], [QTY ADJUST] },
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculated Members' , ASSOCIATED_MEASURE_GROUP = 'Sales';
CREATE MEMBER CURRENTCUBE.[Measures].[Avg Price USD]
AS [Measures].[NET SALES] / [Measures].[SHIP VOLUME],
FORMAT_STRING = "Standard",
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculated Members' , ASSOCIATED_MEASURE_GROUP = 'Sales' ;
CREATE MEMBER CURRENTCUBE.[Measures].[Avg Price CAD]
AS [Measures].[NET SALES CAD] / [Measures].[SHIP VOLUME],
FORMAT_STRING = "Standard",
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculated Members' , ASSOCIATED_MEASURE_GROUP = 'Sales' ;
The syntax works fine, however when I look at my cube through Excel some of the values have #NUM! as the value.. not sure why this is? Is this because of divide by zero issue? How would I work around this?
Maybe check - A/B = C if B not equal 0 ? :
CALCULATE;
/* Calculate Sales Volume */
CREATE MEMBER CURRENTCUBE.[Measures].[Ship Volume]
AS [Measures].[QTY SHIPPED] + [Measures].[QTY ADJUST],
FORMAT_STRING = "Standard",
NON_EMPTY_BEHAVIOR = { [QTY SHIPPED], [QTY ADJUST] },
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculated Members' , ASSOCIATED_MEASURE_GROUP = 'Sales';
CREATE MEMBER CURRENTCUBE.[Measures].[Avg Price USD]
AS Case
When IsEmpty([Measures].[SHIP VOLUME] )
THEN 0
ELSE [Measures].[NET SALES] / [Measures].[SHIP VOLUME] END,
FORMAT_STRING = "Standard",
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculated Members' , ASSOCIATED_MEASURE_GROUP = 'Sales' ;
CREATE MEMBER CURRENTCUBE.[Measures].[Avg Price CAD]
AS Case
When IsEmpty([Measures].[SHIP VOLUME] )
THEN 0
ELSE [Measures].[NET SALES CAD] / [Measures].[SHIP VOLUME] END,
FORMAT_STRING = "Standard",
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculated Members' , ASSOCIATED_MEASURE_GROUP = 'Sales' ;
Also you can try change IsEmpty([Measures].[SHIP VOLUME] )
to [Measures].[SHIP VOLUME]=0
EDIT
Try change this IsEmpty([Measures].[SHIP VOLUME] ) to
[Measures].[SHIP VOLUME] is null OR [Measures].[SHIP VOLUME]=0

Second MDX Query has to return result for each row returned by 1st MDX Query

I have a Situation where I am looking for MDX Guidance.
Environment: SQL Server 2008 R2,SSRS 2008 R2
Dimension:Columns
DimMainProvider :ProviderName
DimAcademicYear:AcademicYear
DimSectorSubjectArea:Estyn
DimLearningAim:LearningAimReference
Fact:Columns
Learnings:MainProviderKey,AgeBandKey,LearningAimKey,SuccessFlag
What I want is
1) For a particular MainProvider Get Top 10 LearningAims by Success Rate and show it in tablix
2) For a each Row on tablix also show Box plot graph which essentially needs Min,Max,Quartile1,Quartile3 success rates of that particular LearningAim across all Mainproviders
What I have is 2 MDX queries
a) one which gets top 10 Activities for a Main Provider (Simplified
Version of MDX below)
WITH
SET Top10LearningAimsForSuccessRate
AS
NonEmpty(
TOPCOUNT([ReportedLearningAims],10,[Measures].[SuccessRate]),
[Measures].[SuccessRate]
)
SELECT
{
[Measures].[SuccessRate]
} ON COLUMNS
,NON EMPTY
{
EXISTS(
Top10LearningAimsForSuccessRate
,,"Learnings")
} ON ROWS
FROM
(
SELECT {[Measures].[TerminatedAssessableLASum]
,[Measures].[SuccessfulLASum]} ON COLUMNS
,{(StrToSet("[DimMainProvider].[ProviderName].&[44]",CONSTRAINED))} On ROWS
FROM [FECube]
)
WHERE
( StrToSet("[DimAcademicYear].[AcademicYear].[AcademicYear].[2009/10]",CONSTRAINED),
StrToSet("[DimSectorSubjectArea].[Estyn].&[2]",CONSTRAINED)
)
b) Another query which accepts LearningAim as a Parameter and does
Statistical Calculations and gives me values (Simplified Version of
MDX below)
WITH
SET ProviderwideLearningAims
AS
ORDER(
NonEmpty( [DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]
)
,[Measures].[SuccessRate],BASC
)
MEMBER [Measures].[MaxValue]
AS
Max(ProviderwideLearningAims,[SuccessRate]),FORMAT_STRING = "Percent"
MEMBER [Measures].[MinValue]
AS
Min(ProviderwideLearningAims,[SuccessRate]),FORMAT_STRING = "Percent"
MEMBER [Measures].[MedianValue]
AS
Median(ProviderwideLearningAims,[SuccessRate]),FORMAT_STRING = "Percent"
Member [Measures].[ProviderCount] As [ProviderwideLearningAims].Count
MEMBER [Measures].[MeanValue]
AS
(SUM(ProviderwideLearningAims,[SuccessRate])/[Measures].[ProviderCount]),FORMAT_STRING = "Percent"
MEMBER [Measures].[LearningAimUniqueName]
AS
[DimLearningAim].[LearningAimReference].CurrentMember.UniqueName
Select
{ [Measures].[LearningAimUniqueName]
,[Measures].[MinValue]
,[Measures].[MaxValue]
,[Measures].[MedianValue]
,[Measures].[MeanValue]
} ON COLUMNS,
{
NonEmpty([DimLearningAim].[LearningAimReference].[LearningAimReference],ProviderwideLearningAims)
} ON ROWS
FROM
(
SELECT
StrToSet("[DimLearningAim].[LearningAimReference].&[50024991]",CONSTRAINED) ON COLUMNS
FROM [FECube]
)
WHERE
( StrToSet("[DimAcademicYear].[AcademicYear].[AcademicYear].[2009/10]",CONSTRAINED),
StrToSet("[DimSectorSubjectArea].[Estyn].&[2]",CONSTRAINED)
)
My original Idea is to fire 2nd query for each Learning Aim received
from 1st query,but I am not able to implement this in SSRS Dataset
Model.
So Now I am back at MDX level and want somehow to merge these
two.
Here is how I fixed it with help from Deepak Puri on MSDN forums
With Set [Top10LearningAims] as TOPCOUNT(
Filter(([ReportedLearningAims]*[DimMainProvider].[ProviderName].MEMBERS),[DimMainProvider].[ProviderName].CURRENTMEMBER
IS STRTOMEMBER("[DimMainProvider].[ProviderName].&[44]") )
,10,[Measures].[TerminatedAssessableLASum]
)
MEMBER [Measures].[MaxValue] AS
Max(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate]),FORMAT_STRING =
"Percent" MEMBER [Measures].[MinValue] AS
Min(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate]),FORMAT_STRING =
"Percent" MEMBER [Measures].[MedianValue] AS
Median(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate]), FORMAT_STRING =
"Percent"
MEMBER [Measures].[MeanValue] AS
Avg(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate]), FORMAT_STRING =
"Percent"
Member [Measures].[ProviderCount] as
Count(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate])) Member [Measures].[PercentileInt25] as
Int((([Measures].[ProviderCount] - 1) * 25) / 100) Member
[Measures].[PercentileFrac25] as (([Measures].[ProviderCount] - 1) *
25) / 100
- [Measures].[PercentileInt25] Member [Measures].[PercentileLo25] as
([Measures].[SuccessRate],
Order(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate],
BASC).Item([Measures].[PercentileInt25]).Item(0)), FORMAT_STRING =
"Percent" Member [Measures].[PercentileHi25] as
([Measures].[SuccessRate],
Order(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate],
BASC).Item([Measures].[PercentileInt25] + 1).Item(0)), FORMAT_STRING =
"Percent" Member [Measures].[Percentile25Value] as
([Measures].[PercentileLo25] * (1 - [Measures].[PercentileFrac25]))
+ ([Measures].[PercentileHi25] * [Measures].[PercentileFrac25]),
FORMAT_STRING = "Percent" Member [Measures].[PercentileInt75] as
Int((([Measures].[ProviderCount] - 1) * 75) / 100) Member
[Measures].[PercentileFrac75] as (([Measures].[ProviderCount] - 1) *
75) / 100
- [Measures].[PercentileInt75] Member [Measures].[PercentileLo75] as
([Measures].[SuccessRate],
Order(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate],
BASC).Item([Measures].[PercentileInt75]).Item(0)), FORMAT_STRING =
"Percent" Member [Measures].[PercentileHi75] as
([Measures].[SuccessRate],
Order(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate],
BASC).Item([Measures].[PercentileInt75] + 1).Item(0)), FORMAT_STRING =
"Percent" Member [Measures].[Percentile75Value] as
([Measures].[PercentileLo75] * (1 - [Measures].[PercentileFrac75]))
+ ([Measures].[PercentileHi75] * [Measures].[PercentileFrac75]),
FORMAT_STRING = "Percent"
select { [Measures].[TerminatedAssessableLASum]
,[Measures].[SuccessfulLASum]
,[Measures].[SuccessRate]
,[Measures].[SectorTerminatedAssessableLASum]
,[Measures].[SectorSuccessfulLASum]
,[Measures].[SectorSuccessRate]
,[Measures].[ProviderCount] ,[Measures].[MinValue]
,[Measures].[MaxValue] ,[Measures].[MeanValue]
,[Measures].[Percentile25Value] ,[Measures].[MedianValue]
,[Measures].[Percentile75Value]} on COLUMNS,
EXISTS(NonEmpty(([DimLearningAim].[LearningAimReference].[LearningAimReference],[DimLearningAim].[LearningAimTitle].[LearningAimTitle]),([Top10LearningAims],[Measures].[SuccessRate]))*NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]),,"Learnings") DIMENSION PROPERTIES
MEMBER_CAPTION,MEMBER_UNIQUE_NAME ON ROWS from FECube WHERE
( StrToSet("[DimAcademicYear].[AcademicYear].[AcademicYear].[2009/10]",CONSTRAINED),
StrToSet("[DimLearnerAgeBand].[AgeBand].[All]",CONSTRAINED),
StrToSet("[DimLearningCourseLength].[CourseLength].[All]",CONSTRAINED),
StrToSet("[DimLearnerEthnicity].[Ethnicity].[All]",CONSTRAINED),
StrToSet("[DimLearnerGender].[Gender].[All]",CONSTRAINED),
StrToSet("[DimDeprivationDecile].[Decile].[All]",CONSTRAINED),
StrToSet("[DimSectorSubjectArea].[Estyn].&[2]",CONSTRAINED),
StrToSet("[DimLearningActivityLevel].[ActivityLevel].[All]",CONSTRAINED),
StrToSet("[DimLearningActivityType].[ActivityType].[All]",CONSTRAINED)
) CELL PROPERTIES VALUE ,BACK_COLOR ,FORE_COLOR ,FORMATTED_VALUE
,FORMAT_STRING ,FONT_NAME ,FONT_SIZE ,FONT_FLAGS