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

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

Related

MDX Sum for an ordered Set

I want to create a measure for the running total of sales.
The customer dimension need to be ordered by their sales amount.
Want I want to get:
H1
Sales
CumSales
B
10
10
C
3
13
A
2
15
Thank you!
If I use
CREATE MEMBER CURRENTCUBE.[Measures].[CumSales]
AS sum({null: [Kunden].[H1].CurrentMember}, [Measures].[ABSTCK In Mille]),
FORMAT_STRING = "Numeric",
NON_EMPTY_BEHAVIOR = { [ABSTCK In Mille] },
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculations' , ASSOCIATED_MEASURE_GROUP = 'SAP Sales';
(H1 is the customer hierachy name and represents the customer)
I get:
H1
Sales
CumSales
A
2
2
B
10
12
C
3
15
What I also managed (and might be used?) is to create the ordered customer Set ("KundenOrderedByABSTCK") and create a measure for the order index ("KundenOrderedByABSTCK_RowNr")
CREATE DYNAMIC SET CURRENTCUBE.[KundenOrderedByABSTCK]
AS order([Kunden].[H1].[H1].Members,[Measures].[ABSTCK In Mille],DESC) ;
//works fine
//Ranking Nr.
CREATE MEMBER CURRENTCUBE.[Measures].[KundenOrderedByABSTCK_RowNr]
AS RANK([Kunden].[H1].CurrentMember, KundenOrderedByABSTCK),
FORMAT_STRING = "0",
NON_EMPTY_BEHAVIOR = { [ABSTCK In Mille] },
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculations' , ASSOCIATED_MEASURE_GROUP = 'SAP Sales';

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

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.

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];

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