Slow MDX Queries - ssas

I have a query which builds a month to date and year to date SSRS report for the current month & year using parameters passed to the query. The problem is that because of there are so many customers, part numbers, etc. the query is taking way too long to execute. Is there any way to write the query better or to speed it up. Sorry, I'm very new to this. Below is the query...
WITH
MEMBER [Measures].[Key for Today] AS
Format
(
Now(),'yyyyMMdd'
)
MEMBER [Measures].[Today string] AS
'[Date].[Dates].[Day].&[' + [Measures].[Key for Today] + ']'
MEMBER [Measures].[Quantity Shipped MTD] AS
Sum
(
MTD([Date].[Dates].CurrentMember)
,[Measures].[Quantity Shipped]
)
MEMBER [Measures].[Quantity Shipped YTD] AS
Sum
(
YTD([Date].[Dates].CurrentMember)
,[Measures].[Quantity Shipped]
)
MEMBER [Measures].[Sales Amount MTD] AS
Sum
(
MTD([Date].[Dates].CurrentMember)
,[Measures].[Sales Amount]
)
MEMBER [Measures].[Sales Amount YTD] AS
Sum
(
YTD([Date].[Dates].CurrentMember)
,[Measures].[Sales Amount]
)
MEMBER [Measures].[Cost Amount MTD] AS
Sum
(
MTD([Date].[Dates].CurrentMember)
,[Measures].[Cost Amount - Sales]
)
MEMBER [Measures].[Cost Amount YTD] AS
Sum
(
YTD([Date].[Dates].CurrentMember)
,[Measures].[Cost Amount - Sales]
)
MEMBER [Measures].[Sales Margin MTD] AS
Sum
(
MTD([Date].[Dates].CurrentMember)
,[Measures].[Sales Margin]
)
MEMBER [Measures].[Sales Margin YTD] AS
Sum
(
YTD([Date].[Dates].CurrentMember)
,[Measures].[Sales Margin]
)
MEMBER [Measures].[Forecast Quantity MTD] AS
Sum
(
MTD([Date].[Dates].CurrentMember)
,[Measures].[Forecast Quantity]
)
MEMBER [Measures].[Forecast Quantity YTD] AS
Sum
(
YTD([Date].[Dates].CurrentMember)
,[Measures].[Forecast Quantity]
)
MEMBER [Measures].[Forecast Turnover MTD] AS
Sum
(
MTD([Date].[Dates].CurrentMember)
,[Measures].[Forecast Total Turnover]
)
MEMBER [Measures].[Forecast Turnover YTD] AS
Sum
(
YTD([Date].[Dates].CurrentMember)
,[Measures].[Forecast Total Turnover]
)
MEMBER [Measures].[Forcast Cost MTD] AS
Sum
(
MTD([Date].[Dates].CurrentMember)
,[Measures].[Forecast Total Cost]
)
MEMBER [Measures].[Forecast Cost YTD] AS
Sum
(
YTD([Date].[Dates].CurrentMember)
,[Measures].[Forecast Total Cost]
)
MEMBER [Measures].[Forecast Margin MTD] AS
Sum
(
MTD([Date].[Dates].CurrentMember)
,[Measures].[Forecast Margin]
)
MEMBER [Measures].[Forecast Margin YTD] AS
Sum
(
YTD([Date].[Dates].CurrentMember)
,[Measures].[Forecast Margin]
)
MEMBER [Measures].[Budget Quantity MTD] AS
Sum
(
MTD([Date].[Dates].CurrentMember)
,[Measures].[Budget Quantity]
)
MEMBER [Measures].[Budget Quantity YTD] AS
Sum
(
YTD([Date].[Dates].CurrentMember)
,[Measures].[Budget Quantity]
)
MEMBER [Measures].[Budget Turnover MTD] AS
Sum
(
MTD([Date].[Dates].CurrentMember)
,[Measures].[Budget Total Turnover]
)
MEMBER [Measures].[Budget Turnover YTD] AS
Sum
(
YTD([Date].[Dates].CurrentMember)
,[Measures].[Budget Total Turnover]
)
MEMBER [Measures].[Budget Cost MTD] AS
Sum
(
MTD([Date].[Dates].CurrentMember)
,[Measures].[Budget Total Cost]
)
MEMBER [Measures].[Budget Cost YTD] AS
Sum
(
YTD([Date].[Dates].CurrentMember)
,[Measures].[Budget Total Cost]
)
MEMBER [Measures].[Budget Margin MTD] AS
Sum
(
MTD([Date].[Dates].CurrentMember)
,[Measures].[Budget Margin]
)
MEMBER [Measures].[Budget Margin YTD] AS
Sum
(
YTD([Date].[Dates].CurrentMember)
,[Measures].[Budget Margin]
)
SELECT
{
[Measures].[Quantity Shipped MTD],
[Measures].[Sales Amount MTD],
[Measures].[Cost Amount MTD],
[Measures].[Sales Margin MTD],
[Measures].[Margin %],
[Measures].[Forecast Quantity MTD],
[Measures].[Forecast Turnover MTD],
[Measures].[Forcast Cost MTD],
[Measures].[Forecast Margin MTD],
[Measures].[Margin %],
[Measures].[Budget Quantity MTD],
[Measures].[Budget Turnover MTD],
[Measures].[Budget Cost MTD],
[Measures].[Budget Margin MTD],
[Measures].[Margin %],
[Measures].[Quantity Shipped YTD],
[Measures].[Sales Amount YTD],
[Measures].[Cost Amount YTD],
[Measures].[Sales Margin YTD],
[Measures].[Margin %],
[Measures].[Forecast Quantity YTD],
[Measures].[Forecast Turnover YTD],
[Measures].[Forecast Cost YTD],
[Measures].[Forecast Margin YTD],
[Measures].[Margin %],
[Measures].[Budget Quantity YTD],
[Measures].[Budget Turnover YTD],
[Measures].[Budget Cost YTD],
[Measures].[Budget Margin YTD],
[Measures].[Margin %]
} ON COLUMNS,
NON EMPTY { (
[Customer].[Customer].[Customer].ALLMEMBERS *
[Customer Sales].[Summary Prod Group 1].[Summary Prod Group 1].ALLMEMBERS *
[Customer Sales].[Vehicle Mode].[Vehicle Mode].ALLMEMBERS *
[Customer Sales].[Part Number].[Part Number].ALLMEMBERS ) }
ON ROWS
FROM ( SELECT ( STRTOSET(#SummaryProdGroup, CONSTRAINED) ) ON COLUMNS
FROM ( SELECT ( STRTOSET(#SalesSummaryCode, CONSTRAINED) ) ON COLUMNS
FROM ( SELECT ( STRTOSET(#BusinessType, CONSTRAINED) ) ON COLUMNS FROM [Sales])))
Where((
StrToMember
(
[Measures].[Today string],constrained
)),
IIF( STRTOSET(#BusinessType, CONSTRAINED).Count = 1, STRTOSET(#BusinessType, CONSTRAINED), [Customer].[Business Type].currentmember ),
IIF( STRTOSET(#SalesSummaryCode, CONSTRAINED).Count = 1, STRTOSET(#SalesSummaryCode, CONSTRAINED), [Customer].[Sales Summary Code].currentmember ))
Thank you

I'd be tempted to try moving the following out of your WHERE clause:
StrToMember
(
[Measures].[Today string],constrained
)
So the WITH clause could then be like the following:
WITH
MEMBER [Measures].[Key for Today] AS
Format
(
Now(),'yyyyMMdd'
)
MEMBER [Measures].[Today string] AS
'[Date].[Dates].[Day].&[' + [Measures].[Key for Today] + ']'
SET [today] AS
StrToSet([Measures].[Today string],constrained)
MEMBER [Measures].[Quantity Shipped MTD] AS
Sum
(
MTD([today].ITEM(0))
,[Measures].[Quantity Shipped]
)
MEMBER [Measures].[Quantity Shipped YTD] AS
Sum
(
YTD([today].ITEM(0))
,[Measures].[Quantity Shipped]
)
...
...

Related

Convert sql rank to mdx rank

This is my sql code - I want to convert it into an mdx query.
Also those results set use into power bi report.
I am unable to write this sql query into mdx query. Can anybody help me?
Select * From(
Select
dense_RANK()over(partition by t.MonthName order by t.amount desc)rank
,t.*
From(
Select DSP.SalesPointShortName ,dd.MonthName
,SUM(fs.salesAmount)Amount
From FactSales FS
INNER JOIN DimDate dd on fs.DateKey=dd.DateKey
INNER JOIN DimSalesPoint DSP on DSP.SalesPointID=FS.SalesPointID
group by dsp.SalesPointShortName ,dd.MonthName
)as t
)as f where f.rank=1
My expected output is:
Lots of google searching i have the answer from below link
After following this link desire results comes.
https://bipassion.wordpress.com/2013/06/22/mdx-dense-rank/
`
WITH SET [Sorted Models] AS
// For each month get Top 25 records, choosed a Top 25 from business case
Generate (
[Dim Date].[Month Name].[Month Name].Members,
TopCount
( nonempty(
{
[Dim Date].[Month Name].CurrentMember
* [Dim Sales Point].[SalesPoint].[Sales Point Short Name].MEMBERS
}
,[Measures].[Sales Amount]
)
, 1
,[Measures].[Sales Amount]
)
)
//Select
//[Measures].[Sales Amount] on 0,[Sorted Models] on 1
//From [MdCubeTest]
//where [Dim Product Group Item].[Sub Category Name].&[Bag]
MEMBER [Measures].[Rank] AS
// Get the Rank of current member Tuple to Current Month Set
// Do not use Sorted Models set due to dynamic for each set
Rank (
(
[Dim Date].[Month Name].CurrentMember
, [Dim Sales Point].[SalesPoint].CurrentMember
)
, Generate ( [Dim Date].[Month Name].CurrentMember,
TopCount
( nonempty(
{ [Dim Date].[Month Name].CurrentMember
* [Dim Sales Point].[SalesPoint].[Sales Point Short Name]
}
,[Measures].[Sales Amount]
)
, 25
,[Measures].[Sales Amount]
)
)
, [Measures].[Sales Amount]
)
MEMBER [Measures].[Previous Set Index] AS
// Get the Set Index using Rank
(
[Measures].[Rank] - 2
)
MEMBER [Measures].[Dense Rank] AS
// Get the Dense Rank using the Index position value
CASE
WHEN [Measures].[Rank] = 1
THEN 1
ELSE
(
[Sorted Models].Item([Measures].[Previous Set Index]),
[Measures].[Dense Rank]
)
+
Iif
(
(
[Sorted Models].Item([Measures].[Previous Set Index]),
[Measures].[Sales Amount]
)
=
[Measures].[Sales Amount]
,0
,1
)
End
SELECT
{
[Measures].[Sales Amount]
, [Measures].[Rank]
, [Measures].[Dense Rank]
//, [Measures].[Previous Set Index]
} ON rows
,NON EMPTY
{
// FILTER Can be used to get the TOP 3 using DENSE RANK
FILTER (
[Sorted Models]
, [Measures].[Dense Rank] <=1
)
} ON columns
FROM [MdCubeTest]
where [Dim Product Group Item].[Sub Category Name].&[Bag]`

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

MDX as Calculated Member in SSAS Cube

I have a FactBudget per sales region with fields [Budget SalesRegion] and [Sales Region]. In the dimension DimCustomer I have the fields [Sales Region] and [Customer Type].
The relation between FactBudget and DimCustomer is defined only on the [Sales Region].
I have a rather simple mdx statement that filters the [Sales Region] of the DimCustomer for a certain [Customer Type]. With the returned [Sales Region] I select the correspondent [Budget SalesRegion]:
SELECT
(
FILTER(
[Kunde].[Sales Region].members
,[Kunde].[Customer Type].CURRENTMEMBER
=[Kunde].[Customer Type].[All].[Direct Sales]
)
,[Measures].[Budget SalesRegion]
) ON 0,
[Kunde].[Customer Type].[All].[Direct Sales] ON 1
FROM [BI_DWH];
How can I translate this statement into an Calculated Member in the SSAS cube so that the selected [Customer Type] in a slicer filters the statement accordingly?
This:
SELECT
(
FILTER(
[Kunde].[Sales Region].members
,[Kunde].[Customer Type].CURRENTMEMBER
=[Kunde].[Customer Type].[All].[Direct Sales]
)
,[Measures].[Budget SalesRegion]
) ON 0,
[Kunde].[Customer Type].[All].[Direct Sales] ON 1
FROM [BI_DWH];
Is the same as this:
SELECT
[Measures].[Budget SalesRegion] ON 0,
[Kunde].[Customer Type].[All].[Direct Sales] ON 1
FROM [BI_DWH];
Or if you want to use the slicer axis:
SELECT
[Measures].[Budget SalesRegion] ON 0
FROM [BI_DWH]
WHERE [Kunde].[Customer Type].[All].[Direct Sales];
Now it is simplified I do not understand what you question is?

MDX How do you create a variance and variance % in a report

Using AdventureWorksDW2008R I have the following DataSet
SELECT NON EMPTY {
[Measures].[Sales Amount], [Measures].[Total Product Cost], [Measures].[Internet Sales Count]
} ON COLUMNS, NON EMPTY
{
([Order Date].[Calendar Year].[Calendar Year].ALLMEMBERS )
} DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME ON ROWS
FROM [Adventure Works Cube]
Resutls are:
Sales Amount Total Product Cost Internet Sales Count
2005 4342674.0296 2562584.6235 8949
2008 25016003.1911002 14715208.9522001 51449
Is there a way to calculate the variance of each in the report?
For example the Variance of Internet Sales Count would be:
51449 – 8949 = 42500
And the % variance would be
42500/51449 = 83%
I know I can use the following to get the Sum:
=Sum(Fields!Internet_Sales_Count.Value, "DataSet1")
Is there a way to get the 2008 value and subtract the 2005 value?
Here is one possibility:
WITH
MEMBER [Measures].[Internet Sales diff] AS
(
[Delivery Date].[Calendar Year].CurrentMember
,[Measures].[Internet Sales Amount]
)
-
(
[Delivery Date].[Calendar Year].CurrentMember.Lag(1)
,[Measures].[Internet Sales Amount]
), format_string = '#,###,###,##0.00'
SELECT
NON EMPTY
{
[Measures].[Sales Amount]
,[Measures].[Total Product Cost]
,[Measures].[Internet Sales Amount]
,[Measures].[Internet Sales diff]
} ON COLUMNS
,NON EMPTY
{[Delivery Date].[Calendar Year].[Calendar Year].ALLMEMBERS}
DIMENSION PROPERTIES
MEMBER_CAPTION
,MEMBER_UNIQUE_NAME
ON ROWS
FROM [Adventure Works];
The result of the above is the following:
A percentage measure could then be added like this:
WITH
MEMBER [Measures].[Internet Sales diff] AS
(
[Delivery Date].[Calendar Year].CurrentMember
,[Measures].[Internet Sales Amount]
)
-
(
[Delivery Date].[Calendar Year].CurrentMember.Lag(1)
,[Measures].[Internet Sales Amount]
)
,format_string = '#,###,###,##0.00'
MEMBER [Measures].[Internet Sales diff %] AS
IIF
(
[Measures].[Internet Sales Amount] = 0
,null
,
[Measures].[Internet Sales diff]
/
(
[Delivery Date].[Calendar Year].CurrentMember.Lag(1)
,[Measures].[Internet Sales Amount]
)
)
,format_string = '#,###,###,##0.00%'
SELECT
NON EMPTY
{
[Measures].[Sales Amount]
,[Measures].[Total Product Cost]
,[Measures].[Internet Sales Amount]
,[Measures].[Internet Sales diff]
,[Measures].[Internet Sales diff %]
} ON COLUMNS
,NON EMPTY
{[Delivery Date].[Calendar Year].[Calendar Year].ALLMEMBERS}
DIMENSION PROPERTIES
MEMBER_CAPTION
,MEMBER_UNIQUE_NAME
ON ROWS
FROM [Adventure Works];
Results in this:
Here is a better approach using the parallelperiod function:
WITH
MEMBER [Measures].[Internet Sales PrevYr] AS
IIF
(
[Measures].[Internet Sales Amount] = 0
,null
,(
[Measures].[Internet Sales Amount]
,ParallelPeriod
(
[Delivery Date].[Calendar Year].[Calendar Year]
,1
,[Delivery Date].[Calendar Year].CurrentMember
)
)
)
,format_string = '$#,###,###,##0.00'
MEMBER [Measures].[Internet Sales diff] AS
IIF
(
[Measures].[Internet Sales Amount] = 0
,null
,
[Measures].[Internet Sales Amount] - [Measures].[Internet Sales PrevYr]
)
,format_string = '$#,###,###,##0.00'
MEMBER [Measures].[Internet Sales diff %] AS
IIF
(
[Measures].[Internet Sales PrevYr] = 0
,null
,
[Measures].[Internet Sales diff] / [Measures].[Internet Sales PrevYr]
)
,format_string = '#,###,###,##0.00%'
SELECT
NON EMPTY
{
[Measures].[Internet Sales Amount]
,[Measures].[Internet Sales PrevYr]
,[Measures].[Internet Sales diff]
,[Measures].[Internet Sales diff %]
} ON COLUMNS
,NON EMPTY
{[Delivery Date].[Calendar Year].[Calendar Year].MEMBERS} ON ROWS
FROM [Adventure Works];
Results:

intersect and topcount and order function in MDX query

I use SQL Server 2008 R2 and i use SSRS and i use Adventure Work DataBase.
I write this MDX query for get 10 city that were in top ten in both years 2003 , 2004.
with
set [Best Cities in CY 2003/2004] as
intersect(
order(
topcount(
[Customer].[Customer Geography].[City],
10,
(
[Measures].[Internet Sales Amount],
[Date].[Calendar].[Calendar Year].[CY 2003]
)
),
[Measures].[Internet Sales Amount],
bdesc
),
order(
topcount(
[Customer].[Customer Geography].[City],
10,
(
[Measures].[Internet Sales Amount],
[Date].[Calendar].[Calendar Year].[CY 2004]
)
),
[Measures].[Internet Sales Amount],
bdesc
)
)
Select [Measures].[Internet Sales Amount] on columns,
[Best Cities in CY 2003/2004] on rows
From [Adventure Works]
Where
{
[Date].[Calendar].[Calendar Year].[CY 2003],
[Date].[Calendar].[Calendar Year].[CY 2004]
}
But i want get list of cities that internet sales has decreased by 35% compared to the previous year and cities among the top 10 cities in the same year as well.
How i can get this result?
You would use Filter for this:
with
set [Best Cities in CY 2003/2004] as
filter(
intersect(
topcount(
[Customer].[Customer Geography].[City],
10,
(
[Measures].[Internet Sales Amount],
[Date].[Calendar].[Calendar Year].[CY 2003]
)
),
topcount(
[Customer].[Customer Geography].[City],
10,
(
[Measures].[Internet Sales Amount],
[Date].[Calendar].[Calendar Year].[CY 2004]
)
)
),
([Measures].[Internet Sales Amount], [Date].[Calendar].[Calendar Year].[CY 2004])
/
([Measures].[Internet Sales Amount], [Date].[Calendar].[Calendar Year].[CY 2003])
- 1.0
< -0.35
)
Select [Measures].[Internet Sales Amount] on columns,
[Best Cities in CY 2003/2004] on rows
From [Adventure Works]
Where
{
[Date].[Calendar].[Calendar Year].[CY 2003],
[Date].[Calendar].[Calendar Year].[CY 2004]
}