In MDX, the price rank of a given number is 0 - mdx

I have an OLAP cube containing the type price sum for each of number.
Using MDX, how can I output the rank of a given number?
Result should be as follows:
Heare is the MDX query, but all rank values are 0. What is wrong in query?
WITH MEMBER [Measures].[Rank Sum of price] AS
RANK([NUM_1].[All Numbers].CURRENTMEMBER
,[NUM_1].[All Numbers]
,[Measures].[Sum of price])
SELECT
{
[Measures].[Sum of price]
, [Measures].[Rank Sum of price]
}
ON COLUMNS,
[NUM_1].[All Numbers]
ON ROWS
FROM schema1

Maybe do your ordering in a custom set before hitting the rank function:
WITH
SET OrderedNums AS
Order
(
[NUM_1].[All Numbers].[All Numbers].MEMBERS
,[Measures].[Sum of price]
,BDESC
)
MEMBER [Measures].[Rank Sum of price] AS
Rank
(
[NUM_1].[All Numbers].CurrentMember
,OrderedNums
)
SELECT
{
[Measures].[Sum of price]
,[Measures].[Rank Sum of price]
} ON 0
,[NUM_1].[All Numbers].[All Numbers].MEMBERS ON 1
FROM schema1;

Related

Convert SQL query to MDX - have Group by & Count Functions

I have the following SQL query which I am trying to convert into MDX:
select avg(skucount)
from
(
SELECT count(distinct [SKUCode]) as skucount
--,[SHOPCODE_WITHOUT_DIST]
FROM [HFPL_DW].[dbo].[FactSecondarySales]
where DISTCODE in
(
SELECT [DISTRIBUTORCODE]
FROM [HFPL_DW].[dbo].[DimDistHierarchy]
where REGION = 'KARACHI'
)
and month(saledate) = 7 and year(saledate) = 2018
group by [SHOPCODE_WITHOUT_DIST]
) as inner_query
The inner query returns the count of SKU saled on each shop(which is fulfilled by using "Group by ShopCode")
First I am trying to convert the inner query to MDX, I have tried the following:
WITH MEMBER [Measures].[SKU Count] AS
COUNT( NonEmpty( { [Product Hierarchy].[SKU].[SKU].Members }, ( [Shop Hierarchy].[SHOPCODE WITHOUT DIST] ) ) )
SELECT
{
[Measures].[SKU Count]
} ON COLUMNS,
NonEmpty(
{ [Product Hierarchy].[SKU].[SKU].Members },
([Shop Hierarchy].[SHOPCODE WITHOUT DIST] )
) ON ROWS
FROM
[Consolidated Sales]
where(
[Time Analysis].[Month].&[2018-07-01T00:00:00],
[Distribution Hierarchy].[DISTRIBUTORCODE].&[1002]
)
Reference: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/51988607-78cc-4520-88db-c6d3e99dd1fc/mdx-to-count-the-number-of-members-in-a-dimension-based-on-another-dimension?forum=sqlanalysisservices
It is not returning anything.
Kindly help me acheive the desired output of the Average SKUs saled(The outer query), the number of SKUs saled per shop (inner query)

Ranking of multiple dimensions, restarting for every year

I have a measure, Sales Amount. I want to rank customers within a divison by year for that measure. I need to also display that rank as a measure. The rank needs to start over every year. I am able to do customers by year and customers by division, but I can't seem to figure out how to combine them both so it iterates over both dimensions properly. Below is what I have for the customers by year. I have tried adding another Division set, creating another named set that I GENERATE with the YearsWithCustomers set, and RANK using that new named set. I seem to be super close to figuring this out but I think I am putting something in the wrong place. I got the idea to iterate over a set from one of Chris Webb's blogs, located here.
WITH
SET Years AS
TopPercent
(
[Sales and Forecast Date].[Calendar Year].[Year Number].MEMBERS
,100
,[Measures].[Sales Amount]
)
SET Customers AS
Filter
(
[Customer].[Customer Number].[Customer Number].MEMBERS
,
[Measures].[Sales Amount] > 0
)
SET YearsWithCustomers AS
Generate
(
Years
,Union
(
{[Sales and Forecast Date].[Calendar Year].CurrentMember}
,StrToSet
("
Intersect({},
{order(Customers,([Sales Amount],[Sales and Forecast Date].[Calendar Year].CurrentMember),desc)
as CustomerSet"
+
Cstr(Years.CurrentOrdinal)
+ "})"
)
)
,ALL
)
MEMBER [Measures].[Customer Rank] AS
Rank
(
[Customer].[Customer Number].CurrentMember
,StrToSet
("CustomerSet"
+
Cstr
(
Rank
(
[Sales and Forecast Date].[Calendar Year].CurrentMember
,Years
)
)
)
)
SELECT
{
[Customer Rank]
,[Measures].[Sales Amount]
} ON 0
,Order
(
Filter
(
(
YearsWithCustomers
,Customers
)
,
[Sales Amount] > 0
)
,[Sales Amount]
,desc
) ON 1
FROM [OrdersAndBudgets];
Here is what I currently have. I would expect to see 1, 2, 3, etc for the Rank measure. It should reset for each division for every year.
I like this sort of pattern:
WITH
SET [AllCountries] AS
[Country].[Country].MEMBERS
SET [AllProds] AS
[Product].[Product].[Product].MEMBERS
SET [Top5Prods] AS
Generate
(
[AllCountries] AS a
,{
(
a.CurrentMember
,[Product].[Product].[All]
)
+
//The top x prods
a.CurrentMember
*
TopCount
(
[AllProds]
,5
,[Measures].[Internet Sales Amount]
)
}
)
MEMBER [Product].[Product].[All].[Other Products] AS
Aggregate
(
[Country].CurrentMember * [Product].[Product].[Product].MEMBERS
-
[Top5Prods]
)
SELECT
{[Measures].[Internet Sales Amount]} ON COLUMNS
,Hierarchize(
{
[Top5Prods]
,[AllCountries] * [Product].[Product].[All].[Other Products]
}
) ON ROWS
FROM [Adventure Works];
It returns the following:
There is quite an extensive thread here: Top X of Top Y with RestOf member where X and Y are hierarchies from different dimensions

Add column in existing MDX

I need to add a column in existing MDX and its values should be 1,1,1,1, and 2,2,2 like below.
Top line income 1
Products (GL) 1
Net Interest Income (NII) 1
Non Interest Revenue (NIR) 1
Products ( Non GL) 1
Net Interest Income (NII) 1
Non Interest Revenue (NIR) 1
WIP (No. of Prospects Logged) 2
WIP (Prospects Total Amount) Exposure 2
WIP (Prospects Total Amount) Deposits 2
Accepted Payouts in Progress (volume) 2
Accepted Payouts in Progress Exposure 2
Approval Rate (%) 2
Rejection Rate (Not taken up) (%) 2
...
...
How to achieve this in existing query?
MDX:
WITH
MEMBER [Measures].[Measure_Key] AS
[ScoreCardMeasures].[ScoreCard].Member_Key
MEMBER [Measures].[Measure_Group_Key] AS
[ScoreCardMeasures].[ScoreCard].Parent.Member_Key
MEMBER [Measures].[Structure_Level] AS
[CustomerStructure].[Provincial Structure].LEVEL_NUMBER
SET [ReportLevel] AS
Filter
(
[Report Levels].[Report Level].[Report Level]
,
Cint([Report Levels].[Report Level].Properties("Structure Level"))
=
Cint([Measures].[Structure_Level])
)
MEMBER [Measures].[Sequence] AS
[ScoreCardMeasures].[ScoreCard].Properties("Sequence")
MEMBER [Measures].[Indent] AS
[ScoreCardMeasures].[ScoreCard].Properties("Font Indent")
MEMBER [Measures].[Weight] AS
[ScoreCardMeasures].[ScoreCard].Properties("Font Weight")
MEMBER [Measures].[Header] AS
[ScoreCardMeasures].[ScoreCard].Properties("Values Header")
MEMBER [Measures].[Header1Caption] AS
[ScoreCardMeasures].[ScoreCard].Properties("Header Name1")
MEMBER [Measures].[Header2Caption] AS
[ScoreCardMeasures].[ScoreCard].Properties("Header Name2")
MEMBER [Measures].[Header3Caption] AS
[ScoreCardMeasures].[ScoreCard].Properties("Header Name3")
MEMBER [Measures].[Actual] AS
[Measures].[Measure Value]
MEMBER [Measures].[Target] AS
[Measures].[Measure Target]
MEMBER [Measures].[Average] AS
[Measures].[Average Value]
SELECT
{
[Measures].[Measure_Key]
,[Measures].[Measure_Group_Key]
,[Measures].[Structure_Level]
,[Measures].[Sequence]
,[Measures].[Indent]
,[Measures].[Weight]
,[Measures].[Header]
,[Measures].[Header1Caption]
,[Measures].[Header2Caption]
,[Measures].[Header3Caption]
,[Measures].[Actual]
,[Measures].[Target]
,[Measures].[Average]
} ON COLUMNS
,{
Filter
(
[ReportLevel]
*
Order
(
Descendants
(
StrToMember(#Financial_Measure)
,[ScoreCardMeasures].[ScoreCard].[Measure Code]
,LEAVES
)
,[Measures].[Sequence]
,ASC
)
,
[Measures].[Active Indicator] <> 0
)
} ON ROWS
FROM [ScoreCard]
WHERE
(
StrToMember(#SiteStructure)
,StrToMember(#Time)
);
I don't fully understand how you decide if it should be a 1 or a 2 - the question does not make it clear.
If you just want it hard-coded into the mdx then this might be an approach:
WITH
MEMBER [Measures].[Measure_Key] AS
[ScoreCardMeasures].[ScoreCard].Member_Key
MEMBER [Measures].[Measure_Group_Key] AS
[ScoreCardMeasures].[ScoreCard].Parent.Member_Key
MEMBER [Measures].[Structure_Level] AS
[CustomerStructure].[Provincial Structure].LEVEL_NUMBER
SET [ReportLevel] AS
Filter
(
[Report Levels].[Report Level].[Report Level]
,
Cint([Report Levels].[Report Level].Properties("Structure Level"))
=
Cint([Measures].[Structure_Level])
)
MEMBER [Measures].[Sequence] AS
[ScoreCardMeasures].[ScoreCard].Properties("Sequence")
MEMBER [Measures].[Indent] AS
[ScoreCardMeasures].[ScoreCard].Properties("Font Indent")
MEMBER [Measures].[Weight] AS
[ScoreCardMeasures].[ScoreCard].Properties("Font Weight")
MEMBER [Measures].[Header] AS
[ScoreCardMeasures].[ScoreCard].Properties("Values Header")
MEMBER [Measures].[Header1Caption] AS
[ScoreCardMeasures].[ScoreCard].Properties("Header Name1")
MEMBER [Measures].[Header2Caption] AS
[ScoreCardMeasures].[ScoreCard].Properties("Header Name2")
MEMBER [Measures].[Header3Caption] AS
[ScoreCardMeasures].[ScoreCard].Properties("Header Name3")
MEMBER [Measures].[Actual] AS
[Measures].[Measure Value]
MEMBER [Measures].[Target] AS
[Measures].[Measure Target]
MEMBER [Measures].[Average] AS
[Measures].[Average Value]
MEMBER [Measures].[1or2] AS
CASE
WHEN
[ScoreCardMeasures].[ScoreCard].CurrentMember
IS
[ScoreCardMeasures].[ScoreCard].[Measure Code].[Top Line Income]
THEN 1
WHEN
[ScoreCardMeasures].[ScoreCard].CurrentMember
IS
[ScoreCardMeasures].[ScoreCard].[Measure Code].[Products (GL)]
THEN 1
WHEN
[ScoreCardMeasures].[ScoreCard].CurrentMember
IS
[ScoreCardMeasures].[ScoreCard].[Measure Code].[WIP (No. of Prospects Logged)]
THEN 2
WHEN
[ScoreCardMeasures].[ScoreCard].CurrentMember
IS
[ScoreCardMeasures].[ScoreCard].[Measure Code].[WIP (Prospects Total Amount) Exposure]
THEN 2
END
SELECT
{
[Measures].[Measure_Key]
,[Measures].[Measure_Group_Key]
,[Measures].[Structure_Level]
,[Measures].[Sequence]
,[Measures].[Indent]
,[Measures].[Weight]
,[Measures].[Header]
,[Measures].[Header1Caption]
,[Measures].[Header2Caption]
,[Measures].[Header3Caption]
,[Measures].[Actual]
,[Measures].[Target]
,[Measures].[Average]
,[Measures].[1or2]
} ON COLUMNS
,{
Filter
(
[ReportLevel]
*
Order
(
Descendants
(
StrToMember(#Financial_Measure)
,[ScoreCardMeasures].[ScoreCard].[Measure Code]
,LEAVES
)
,[Measures].[Sequence]
,ASC
)
,
[Measures].[Active Indicator] <> 0
)
} ON ROWS
FROM [ScoreCard]
WHERE
(
StrToMember(#SiteStructure)
,StrToMember(#Time)
);

MDX, first SUM then AVERAGE

I have a fact model that contains the following data:
WorkOrderNumber | WorkOrderLineNumber | Cost
So I have a dimension WorkOrder:
[WorkOrder].[WorkOrderNumber]
[WorkOrder].[WorkOrderLineNumber]
And a Measure group with the following Measure:
[Measures].[Cost]
I am trying to create a calculate measure:
[Measures].[Average WorkOrder Cost]
This must be calculated by Summing up the values per Work Order and afterwards taking an average of all these sums per workorders.
However I can not seem to get it working.
CASE WHEN [WorkOrder].[WorkOrder].CurrentMember = [WorkOrder].[WorkOrder].[All]
THEN
/* the work order is not selected -> AVG*/
DIVIDE(SUM(),[Measures].[Cost]), Count()) ))
ELSE
/* the Work Order is selected -> SUM*/
SUM([Measures].[Cost])
END
Here is an example of taking an average per sales order using the Adventure Works cube. You could replace with your [Cost] and [WorkOrderNumber]...
with member [CalculatedAvg] as
AVG([Internet Sales Order Details].[Sales Order Number].[Sales Order Number], [Measures].[Internet Sales Amount])
, FORMAT_STRING = "$#,##0.00"
select
{
[Measures].[Internet Sales Amount],
[Measures].[Internet Order Count],
[Measures].[Internet Average Sales Amount],
[CalculatedAvg]
} on 0,
[Date].[Calendar].[Calendar Year].members on 1
from
[Direct Sales]
for example...
AVG([WorkOrder].[WorkOrderNumber].[WorkOrderNumber], [Measures].[Cost])

Calculating total Amount of Internet Sales (AdventureWorks data) MDX

How can I count the total number of sales in the "FactInternetSales" table for the selected member of the DATES hierarchy?
(
[Order Date].[DATES].CURRENTMEMBER,
COUNT(DISTINCT([Fact Internet Sales].[Sales Order Number].[Sales Order Number]
)
this is what I have at the moment however it doesn't work :/
Try count on the outside with extra braces to indicate a set of tuples:
COUNT(
{
[Order Date].[DATES].CURRENTMEMBER
*
[Fact Internet Sales].[Sales Order Number].[Sales Order Number]
}
)
with set abc as
EXISTS([Fact Internet Sales].[Sales Order Number].[Sales Order Number],
[Order Date].[DATES].CURRENTMEMBER,
"Fact Internet Sales"
)
member [Measures].[Count]
AS Count(Distinct(abc))
SELECT [Measures].[Count] on 0
from [YourCube]
WHERE Order Date].[DATES].&[01/01/2015] --Some random value for slicer