Closing Period Percentage MDX - ssas

Bit of a newbie to MDX, I have been struggling with this and need help.
I have a Date Hierarchy, and I can work out the count of cases for the latest loaded quarter, but I am struggling with working out the percentage.
My query is this:
Member [Measures].[Latest Available Full Quarter Percentage]
As
(
ClosingPeriod
(
[Dates].[Quarter].[Quarter]
,[Dates].[Quarter].DefaultMember
)
,[Measures].[Count]
)
Select
[Measures].[Latest Available Full Quarter Percentage] On Columns
,[Things].[Category].Members On Rows
From [Stuff]
The output is like this:
Latest Available Full Quarter Percentage
All 73
Thing1 5
Thing2 12
Thing3 (null)
Thing4 1
Thing5 32
Thing6 9
Thing7 (null)
Thing8 13
Thing9 5
Thing10 6
What I want to do it produce a percentage for each row, the divisor would be 73, and the output would look so:
Latest Available Full Quarter Percentage
All 100%
Thing1 6.8%
Thing2 16.4%
Thing3 0%
Thing4 1.4%
Thing5 43.8%
Thing6 12.3%
Thing7 0%
Thing8 17.8%
Thing9 6.8%
Thing10 8.2%
I just can't figure out how to make the 73 figure static for each row so the percentage calculation can be performed.
Can anyone assist and point out where I have gone wrong?
Edit:
I imagine the solution to be along the same lines as this:
Member [Measures].[Latest Available Full Quarter Percentage]
As
(
ClosingPeriod
(
[Dates].[Quarter].[Quarter]
,[Dates].[Quarter].DefaultMember
)
,[Measures].[Count]
)
/
(
ClosingPeriod
(
[Dates].[Quarter].[Quarter]
,[Dates].[Quarter].DefaultMember
)
,[Measures].[Count]
).Parent
Select
[Measures].[Latest Available Full Quarter Percentage] On Columns
,[Things].[Category].Members On Rows
From [Stuff]
This wont work, but I feel its along these lines
The key point is the calculation needs to stay the same as the members expand.
Edit Part 2:
Have figured this for the specified dimension, we are looking at:
Member [Measures].[Latest Available Full Quarter Percentage]
As
(
ClosingPeriod
(
[Dates].[Quarter].[Quarter]
,[Dates].[Quarter].DefaultMember
)
,[Measures].[Distinct Count]
)
/
(
[Complaints Category].[Category].[All]
,
(
ClosingPeriod
(
[Dates].[Quarter].[Quarter]
,[Dates].[Quarter].DefaultMember
)
,[Measures].[Distinct Count]
)
)
,Format_String = "Percent"
Select
[Measures].[Latest Available Full Quarter Percentage] On Columns
,[Things].[Category].Members On Rows
From [Stuff]
Which gives me:
Latest Available Full Quarter Percentage
All 100%
Thing1 6.85%
Thing2 16.44%
Thing3 (null)
Thing4 1.37%
Thing5 43.84%
Thing6 12.33%
Thing7 (null)
Thing8 17.81%
Thing9 6.85%
Thing10 8.22%
Next challenge though, to get this to work across different dimensions
Any suggestions in the meantime, gladly accepted

I may well be misunderstanding but you can just do a normal division in your caculation - either with the operator / or via the function DIVIDE:
WITH
MEMBER [Measures].[cnt2]
(
ClosingPeriod(
[Dates].[Quarter].[Quarter]
,[Dates].[Quarter].DefaultMember
)
,[Measures].[Count]
,[Things].[Category].[All] //<< added to this tuple to reference All member
)
MEMBER [Measures].[cnt] AS
COUNT([Things].[Category].Members)
MEMBER [Measures].[Latest Available Full Quarter Percentage] AS
DIVIDE(
(
ClosingPeriod(
[Dates].[Quarter].[Quarter]
,[Dates].[Quarter].DefaultMember
)
,[Measures].[Count]
)
, [Measures].[cnt2] //<< changed to cnt2
), FORMAT_STRING="##.00%"
SELECT
[Measures].[Latest Available Full Quarter Percentage] ON COLUMNS
,[Things].[Category].Members ON ROWS
FROM [Stuff];

Related

How to query 3 month running average from SSAS Multidimensional Cube (MDX) for each date?

I have SSAS Multidimensional Cube and I need to query 3 month running average for each day in date range.
For example, for 2016-04-25 I must to get data from 2016-01-01 to 2016-03-31.
So I can't use this query (because I don't know how much days I must lag till previous month):
WITH MEMBER [Measures].[SalesAmount 3m average] AS
(
SUM(
([Date].[Date].CurrentMember.Lag(90) :
([Date].[Date].CurrentMember.Lag(1),
[Measures].[SalesAmount]
)
)
I guess I need to use Ancestor function to get month and use lag to month granularity.
Ok, let's try this one:
WITH MEMBER [Measures].[SalesAmount 3m average] AS
(
SUM(
(Ancestor ( [Date].[Date].CurrentMember, [Date].[Month] )).Lag(3) :
(Ancestor ( [Date].[Date].CurrentMember, [Date].[Month] )).Lag(1),
[Measures].[SalesAmount]
)
)
SELECT { [Measures].[SalesAmount 3m average] } ON Columns,
{ [Date].[Date].&[2016-01-01T00:00:00] : [Date].[Date].&[2016-02-28T00:00:00]} On Rows
FROM [Cube]
Unfortunately, this query doesn't work properly (returns null).
How to solve this problem?
UPDATED:
Ok, I tryed to query member caption:
MEMBER [Measures].[Test] AS
(
(Ancestor
( [Date].[Date].CurrentMember,
[Date].[Date].[Month] )
).Item(0).Member_Caption
)
And I'm getting not a Month caption, but a Date(Day) - the same date as [Date].[Date].CurrentMember.
Then I tryed this queries:
--First try
MEMBER [Measures].[Test] AS
(
IsAncestor([Date].[Date].CurrentMember, [Date].[Month].&[2016-05-01T00:00:00])
)
--Second try
MEMBER [Measures].[Test] AS
(
IsAncestor([Date].[Date].CurrentMember, [Date].[Date].[Month].&[2016-05-01T00:00:00])
)
--Third try
MEMBER [Measures].[Test] AS
(
IsAncestor([Date].[Date].CurrentMember, [Date].[Year - Quarter - Month - Date].[Month].&[2016-05-01T00:00:00])
)
In all queries result was "False". So, Month member not an ancestor to Date members??? Now I'm really confused.
My Date dimension looks like this:
UPDATE 2:
MEMBER [Measures].[Test] AS
(
(Ancestor
( [Date].[Date].CurrentMember,
1 )
).Member_Caption
)
Returns: All
Your code seems fine. I'd add item(0) in a couple of places to make things more obvious but this shouldn't change much
WITH
MEMBER [Measures].[SalesAmount 3m average] AS
Sum
(
Ancestor
(
[Date].[Calendar].CurrentMember
,[Date].[Calendar].[Month]
).Item(0).Lag(3)
:
Ancestor
(
[Date].[Calendar].CurrentMember
,[Date].[Calendar].[Month]
).Item(0).Lag(1)
,[Measures].[Internet Sales Amount]
)
SELECT
{[Measures].[SalesAmount 3m average]} ON COLUMNS
,{
[Date].[Calendar].[Date].&[20060222]
:
[Date].[Calendar].[Date].&[20060722]
} ON ROWS
FROM [Adventure Works];
Returns this:
Check that all your level expressions are correct:
[Date].[Date] ?
and
[Date].[Month] ?
Also as a further test what does this return?
WITH
MEMBER [Measures].[test1] AS
Ancestor
(
[Date].[Date].CurrentMember
,[Date].[Month]
).Item(0).Lag(3).Member_Caption
MEMBER [Measures].[test2] AS
Ancestor
(
[Date].[Date].CurrentMember
,[Date].[Month]
).Item(0).Lag(1).Member_Caption
SELECT
{
[Measures].[test1]
,[Measures].[test2]
} ON COLUMNS
,{
[Date].[Date].&[2016-01-01T00:00:00]
:
[Date].[Date].&[2016-02-28T00:00:00]
} ON ROWS
FROM [Cube];
Ancestor will function between different levels of the same hierarchy ie:
What this means is that [Date].[Date] and [Date].[Month] are not really related via Ancestor. Try this:
WITH
MEMBER [Measures].[SalesAmount 3m average] AS
(
SUM(
Ancestor (
[Date].[Year - Quarter - Month - Date].CurrentMember,
[Date].[Year - Quarter - Month - Date].[Month] ).Lag(3)
:
Ancestor(
[Date].[Year - Quarter - Month - Date].CurrentMember
,[Date].[Year - Quarter - Month - Date].[Month] ).Lag(1)
,[Measures].[SalesAmount]
)
)
SELECT
{ [Measures].[SalesAmount 3m average] } ON Columns,
{
[Date].[Year - Quarter - Month - Date].[Date].&[2016-01-01T00:00:00]
: [Date].[Year - Quarter - Month - Date].[Date].&[2016-02-28T00:00:00]
//I suspect the above 2 lines can be replaced by following:
// [Date].[Date].&[2016-01-01T00:00:00]
//: [Date].[Date].&[2016-02-28T00:00:00]
}
On Rows
FROM [Cube];
note
This should return All because the hierarchy [Date].[Date] only has two levels ... the leaf level are the dates with a single level above that All:
MEMBER [Measures].[Test] AS
(
(Ancestor
( [Date].[Date].CurrentMember,
1 )
).Member_Caption
)

MDX query with nested aggregations

WITH
MEMBER [Measures].[newCalculatedMeasure] AS
Sum
(
Filter
(
Descendants
(
[Date].[28 Days Month Calendar].CurrentMember
,2
,LEAVES
)
,
[Measures].[mymeasure] * 10
>
Avg
(
Filter
(
Descendants
(
[Date].[28 Days Month Calendar].CurrentMember
,2
,LEAVES
)
,
[Measures].[mymeasure] > 0
)
,[Measures].[mymeasure]
)
)
,[Measures].[mymeasure]
)
SELECT
[Date].[28 Days Month Calendar].MEMBERS ON 0
,[Measures].[newCalculatedMeasure] ON 1
FROM [cube];
Above query is not evaluating the inside average function, whereas if i replace that with the actual average, its working fine
Can somebody tell me whats wrong with the above measure..
Does splitting the measure into named sets help with this context issue?
WITH
SET [MYSET] AS
Descendants
(
[Date].[28 Days Month Calendar].CurrentMember
,2
,LEAVES
)
SET [MYSETFILTERED] AS
Filter
(
[MYSET]
,
[Measures].[mymeasure] > 0
)
MEMBER [Measures].[newCalculatedMeasure] AS
Sum
(
Filter
(
[MYSET]
,
[Measures].[mymeasure] * 10 > Avg([MYSETFILTERED],[Measures].[mymeasure])
)
,[Measures].[mymeasure]
)
SELECT
[Date].[28 Days Month Calendar].MEMBERS ON 0
,[Measures].[newCalculatedMeasure] ON 1
FROM [cube];
Named sets with aggregates can sometimes impact performance so please excuse me if the above slows everything up.

Exclude a member for MDX forecasting using linear regression

I want to forecast measure value for the next month using data from complete previous months.
For example in this moment September 11, I have to forecast the value of the September month (cause the September month is not over) based on January-August values.
I am using MDX function LinRegPoint with the hierarchy detailed below
DimTime
Hierarchy Time
Year
Quarter
Month
This is the query I been trying without success:
WITH
MEMBER [Measures].[Trend] AS
LinRegPoint
(
Rank
(
[Time].[Hierarchy Time].CurrentMember
,[Time].[Hierarchy Time].CurrentMember.Level.MEMBERS
)
,Descendants
(
[Time].[Hierarchy Time].[2015]
,[Time].[Hierarchy Time].CurrentMember.Level
)
,[Measures].[Quality]
,Rank
(
[Time].[Hierarchy Time]
,[Time].[Hierarchy Time].Level.MEMBERS
)
)
SELECT
{
[Measures].[Quality]
,[Measures].[Trend]
} ON COLUMNS
,Descendants
(
[Time].[Hierarchy Time].[2015]
,[Time].[Hierarchy Time].[Month]
) ON ROWS
FROM [Cube];
The above query return all month forecasted values to today date including the September month, however It forecasts the September value taking the real values from January to September current date. I need the LinRegPoint function just takes the previous complete months in this case January to August.
Note the query returns a forecasted value for 9 month (September) but it is using the real value to calculate it. It would result in a misunderstood line as shown in the below images.
This image shows the drawn line taking the previous full-month (1-8):
Note the positive slope line.
This image shows the drawn line taking all months (1-9)
Note the negative slope line.
Question:
How can I exclude the no complete current month from real values but allowing the forecasted value be calculated.
EDIT:
The set should be changing to exclude the last month member in real values but calculating the forecasted value for it.
Thanks for considering my question.
SOLUTION:
WITH MEMBER [Measures].[Trend] AS
LinRegPoint
(
Rank(
[Time].[Hierarchy Time].CurrentMember
,[Time].[Hierarchy Time].CurrentMember.Level.MEMBERS
)
,Descendants
(
[Time].[Hierarchy Time].[2015]
,[Time].[Hierarchy Time].CurrentMember.Level
)
,[Measures].[QltyNoCurrentVal]
,Rank(
[Time].[Hierarchy Time]
,[Time].[Hierarchy Time].Level.MEMBERS)
),FORMAT_STRING='Standard' //Formating
MEMBER [Measures].[QltyNoCurrentVal] AS
IIF(
[Time].[Hierarchy Time].CurrentMember is [Time].[Hierarchy Time].[2015].[3].[9]
, NULL
, [Measures].[Quality]
),FORMAT_STRING='Standard' //Formating
select {
[Measures].[QltyNoCurrentVal]
,[Measures].[Trend]} ON COLUMNS
,Descendants(
[Time].[Hierarchy Time].[2015]
,[Time].[Hierarchy Time].[Month]
) ON ROWS
FROM [Cube]
Slightly confused which sets in your expression need changing.
I've created a set [MthsExclSept] which you should be able to use anywhere in the rest of your script - I've just used it in two places:
WITH
SET [MthsExclSept] AS
SubSet
(
Descendants
(
[Time].[Hierarchy Time].[2015]
,[Time].[Hierarchy Time].[Month] //<<better to specify the month level
)
,0
,
Descendants
(
[Time].[Hierarchy Time].[2015]
,[Time].[Hierarchy Time].[Month] //<<better to specify the month level
).Count
- 1
)
MEMBER [Measures].[Trend] AS
LinRegPoint
(
Rank
(
[Time].[Hierarchy Time].CurrentMember
,[MthsExclSept] //<<also added here?
)
,[MthsExclSept]
,[Measures].[Quality]
,Rank
(
[Time].[Hierarchy Time]
,[MthsExclSept] //<<also added here?
)
)
MEMBER [Measures].[QualityNEW] AS
IIF(
[Time].[Hierarchy Time].CurrentMember is [Time].[Hierarchy Time].[September]
, NULL
, [Measures].[Quality]
)
SELECT
{
[Measures].[QualityNEW]
,[Measures].[Trend]
} ON COLUMNS
,[MthsExclSept] ON ROWS
FROM [Cube];
The set [MthsExclSept] just trims off the last month. Here is a proof via AdvWrks that trims of December from a year:
WITH
SET [MthsExclSept] AS
SubSet
(
Descendants
(
[Date].[Calendar].[Calendar Year].&[2009]
,[Date].[Calendar].[Month]
)
,0
,
Descendants
(
[Date].[Calendar].[Calendar Year].&[2009]
,[Date].[Calendar].[Month]
).Count
- 1
)
SELECT
{} ON 0
,[MthsExclSept] ON 1
FROM [Adventure Works];
It returns the following:

MDX for Zero months in last 12 = Number of zero transacting months in the last 12 months rolling window

I am working on MDx query to count the number ZERO txn for each product for last 12 months from today's date. Prepared MDX query for Adventure works fine but my 2nd query running on my Acutal cube working correctly.
Can you please help me out to rectify the query or any filter needed to get correct results like 1st sample query?
1st Sample Query on Adventure Works: (working correctly)
WITH Member [Measures].[Months With Zero Sales] AS
COUNT(
FILTER(
DESCENDANTS(
{[Date].[Calendar].[Month].&[2008]&[1].LAG(12):[Date].[Calendar].[Month].&[2008]&[1]}, [Date].[Calendar].[Month]) ,
[Measures].[Sales Amount] = 0 ) )
SELECT {[Measures].[Months With Zero Sales]} ON 0,
[Product].[Product Model Lines].[Product Line].Members on 1
FROM [Adventure Works];
Product Lines Months With Zero Sales]
----------- -----------------
Accessory 0
Componenets 0
Mountain 0
Road 0
Touring 6
2nd Query on my Cube:
WITH Member [Measures].[Zero Months in last 12] AS
COUNT(
FILTER(
DESCENDANTS(
{[Settlement Date].[Calendar].[Settlement Calendar Month].&[2014]&[1].LAG(12):
[Settlement Date].[Calendar].[Settlement Calendar Month].&[2014]&[1]},
[Settlement Date].[Calendar].[Settlement Calendar Month]),
[Measures].[Transaction Count] = 0 ) )
SELECT {[Measures].[Transaction Count] ,[Measures].[Zero Months in last 12]} ON 0,
[Terminal].[terminal ID].members on 1
FROM [cubetxn]
I'm expecting if non zero where "transaction count" is (null), even if there is transaction count not null, there could be chances to have one month with empty tuples.
Can you please correct my query or someone can give me sample query which should able to give me total zero month txn count for last 12 month of each product.
Terminal ID Transaction Count Zero Months in last 12
---------- ----------------- -------------------------
All Terminals 504,112,053 0
Q1001 138,832 0
Q1002 (null) 0
Q1003 88,800 0
Q1004 (null) 0
First comment is that this is a quicker pattern to use when doing a count/filter:
WITH
MEMBER [Measures].[Months With Zero Sales] AS
Sum
(
Descendants
(
{
[Date].[Calendar].[Month].&[2008]&[1].Lag(12)
:
[Date].[Calendar].[Month].&[2008]&[1]
}
,[Date].[Calendar].[Month]
)
,IIF
(
[Measures].[Sales Amount] = 0
,1
,null
)
)
SELECT
{[Measures].[Months With Zero Sales]} ON 0
,[Product].[Product Model Lines].[Product Line].MEMBERS ON 1
FROM [Adventure Works];
Based on this more efficient approach does the following work?
WITH
MEMBER [Measures].[Zero Months in last 12] AS
Sum
(
Descendants
(
{
[Settlement Date].[Calendar].[Settlement Calendar Month].&[2014]&[1].Lag(12)
:
[Settlement Date].[Calendar].[Settlement Calendar Month].&[2014]&[1]
}
,[Settlement Date].[Calendar].[Settlement Calendar Month]
)
,IIF
(
[Measures].[Transaction Count] = 0
,1
,0
)
)
SELECT
{
[Measures].[Transaction Count]
,[Measures].[Zero Months in last 12]
} ON 0
,[Terminal].[terminal ID].MEMBERS ON 1
FROM [cubetxn];
If there is still a problem then why not reconstruct your script so you can manually check what to expect. So for the AdvWrks script I'd run this so that I could actually confirm that the 6 is correct:
SELECT
{[Measures].[Sales Amount]} ON 0
,
Descendants
(
{
[Date].[Calendar].[Month].&[2008]&[1].Lag(12)
:
[Date].[Calendar].[Month].&[2008]&[1]
}
,[Date].[Calendar].[Month]
)
*
[Product].[Product Model Lines].[Product Line].MEMBERS ON 1
FROM [Adventure Works];
So against your cube what does the following return?
SELECT
{[Measures].[Transaction Count]} ON 0
,
Descendants
(
{
[Settlement Date].[Calendar].[Settlement Calendar Month].&[2014]&[1].Lag(12)
:
[Settlement Date].[Calendar].[Settlement Calendar Month].&[2014]&[1]
}
,[Settlement Date].[Calendar].[Settlement Calendar Month]
)
*
[Terminal].[terminal ID].MEMBERS ON 1
FROM [cubetxn];
//Total Transactions count Weekend Sunday (i’ve date dimesion which holds day_in_week=’Sun’ for respective dates)
WITH SET AllTranSundays as
EXISTS(DATE.DATE.DATE.MEMBERS, DATE.DATE.day_in_week.&[Sun], "Sales")
//Count of all sundays which had transactions.
MEMBER Measures.CntAllTranSundays AS
COUNT(AllTranSundays)
//YTD Days = Count of days within calendar year to date
MEMBER Measures.CntDaysYTD as
COUNT(DESCENDANTS(ANCESTOR([DATE].[date].CURRENTMEMBER,
3), 3).item(0).item(0)
: [DATE].[date].CURRENTMEMBER)
//YTD Transactions = Transaction count year to date
MEMBER Measures.CntTranYTD as
COUNT(
EXISTS(
{DESCENDANTS(ANCESTOR([DATE].[date].CURRENTMEMBER,
3), 3).item(0).item(0)
: [DATE].[date].CURRENTMEMBER}, , "Sales"
)
//Zero months in last 12 = Number of zero transacting months in the last 12 months rolling window
MEMBER Measures.CntZeroTransactingMonths as
COUNT(
{ANCESTOR([DATE].[date].CURRENTMEMBER, 1).ITEM(0).LAG(12) : ANCESTOR([DATE].[date].CURRENTMEMBER, 1).ITEM(0)}
-
EXISTS({ANCESTOR([DATE].[date].CURRENTMEMBER, 1).ITEM(0).LAG(12) : ANCESTOR([DATE].[date].CURRENTMEMBER, 1).ITEM(0)}
, ,
"Sales")
)
//Consecutive zero months = Number of consecutive zero transacting months in last 12 months rolling window
Question Do you want a count of instances when consecutive months had zero transactions.
Or do you want a count of number of months which had consecutively no transactions?
What I am trying to say is say Jan, March, June, July, August, October, November had no transactions in the rolling last 12 months
As per case 1: the answer should be 2
As per case 2: the answer should be 5.
Will update my answer as per your clarification.
SELECT
{Measures.CntAllTranSundays, Measures.CntDaysYTD, Measures.CntTranYTD, Measures.CntZeroTransactingMonths} ON 0
FROM [YourCube]
where
[date].[date].[date].&[02/28/2015]

MDX Count over time (years - not within a year)

I'd like to be able to rollup the count of commitments to a product over years -
The data for new commitments in each year looks like this:
Year | Count of new commitments | (What I'd like - count of new commitments to date)
1986 4 4
1987 22 26
1988 14 40
1989 1 41
I know that within a year you can do year to date, month to date etc, but I need to do it over multiple years.
the mdx that gives me the first 2 columns is (really simple - but I don't know where to go from here):
select [Measures].[Commitment Count] on 0
, [Date Dim].[CY Hierarchy].[Calendar Year] on 1
from [Cube]
Any help would be great
In MDX something along the line:
with member [x] as sum(
[Date Dim].[CY Hierarchy].[Calendar Year].members(0) : [Date Dim].[CY Hierarchy].currentMember,
[Measures].[Commitment Count]
)
select [x] on 0, [Date Dim].[CY Hierarchy].[Calendar Year] on 1 from [Cube]
Use a common table expression:
with sums (year,sumThisYear,cumulativeSum)
as (
select year
, sum(commitments) as sumThisYear
, sum(commitments) as cumulativeSum
from theTable
where year = (select min(year) from theTable)
group by year
union all
select child.year
, sum(child.commitments) as sumThisYear
, sum(child.commitments) + parent.cumulativeSum as cumulativeSum
from sums par
JOIN thetable Child on par.year = child.year - 1
group by child.year,parent.cumulativeSum
)
select * from sums
There's a bit of a "trick" in there grouping on parent.cumulativeSum. We know that this will be the same value for all rows, and we need to add it to sum(child.commitments), so we group on it so SQL Server will let us refer to it. That can probably be cleaned up to remove what might be called a "smell", but it will work.
Warning: 11:15pm where I am, written off the top of my head, may need a tweak or two.
EDIT: forgot the group by in the anchor clause, added that in