Calculating Avg Orders per day using MDX - ssas

I am trying to create a calculated member which should returns the averages orders per week per person.
Below is the screen shot where the client will be looking to forecast the work load. Staff may not work all the days in a week.
The calculation will be : No of Orders / No of scheduled days in that week.
It would not be very hard to calculate this if the week name is in the same hierarchy of the date, but in this case it is not in hierarchy but just member of the dimension.
This is the MDX I've tried:
Avg ( Descendants
( [Date Planned].[Date Planned].CurrentMember, [Date Planned].[Date Planned].[Date Planned] ),
[Measures].[Orders Qty] )

It would be much easier when you have week and day added into the hierarchy, but if you don't have possibility to have this added, there is different non elegant solution.
If you would assume that this member will always be used with Week on rows your member calculation would be as follow:
This will work correctly only with weeks on rows - so I would recommend to extend your Calendar hierarchy by week and day and then we can have a chat about much more elegant solution.

Try using this:
WITH MEMBER [Measures].[avg_week] AS
Avg ( EXISTING { [Date Planned].[Week Of Year].[Week Of Year] },
[Measures].[Orders Qty] )
SELECT [Measures].[avg_week] ON COLUMNS,
NON EMPTY
{ [Person].[PersonName].[PersonName] * [Date Planned].[Week Of Year].[Week Of Year] } ON ROWS
FROM [Your cube]
Let me know if this can help you.

Maybe something like the following:
WITH
MEMBER [Measures].[PlannedDayCnt] AS
Count
(
Exists
(
(EXISTING
[Date Planned].[Date Planned].[Date Planned].MEMBERS)
,[Date Planned].[Week Of Year].currentmember
)
)
MEMBER [Measures].[Averge Orders] AS
[Measures].[Orders Qty] / [Measures].[PlannedDayCnt]
SELECT
{
[Measures].[Orders Qty]
,[Measures].[PlannedDayCnt]
,[Measures].[Averge Orders]
} ON 0
,
[Person].[PersonName].[PersonName]
* [Date Planned].[Week Of Year].[Week Of Year] ON 1
FROM [aCube];
I'd like to test but unsure how to model your scenario in the AdvWrks cube.

I would first want to see how many "dates" belong to the week. That would be easy as it would be those days when Orders were placed for that person that week.
NonEmpty
(
[Date Planned].[Date Planned].[Date Planned].MEMBERS,
(
[Date Planned].[Week Of Year].currentmember,
[Person].[PersonName].currentmember,
[Measures].[Orders Qty]
)
)
Now that you have the requisite dates for the "current" week and the "current" person, you would need to calculate the average order quantity for these set of dates. It would look like this:
AVG
(
NonEmpty
(
[Date Planned].[Date Planned].[Date Planned].MEMBERS,
(
[Date Planned].[Week Of Year].currentmember,
[Person].[PersonName].currentmember,
[Measures].[Orders Qty]
)
)
, [Measures].[Orders Qty]
)
Your final construct would need to be:
WITH MEMBER Measures.AverageOrderPerDay AS
AVG
(
NonEmpty
(
[Date Planned].[Date Planned].[Date Planned].MEMBERS,
(
[Date Planned].[Week Of Year].currentmember,
[Person].[PersonName].currentmember,
[Measures].[Orders Qty]
)
)
, [Measures].[Orders Qty]
)
SELECT
{
[Measures].AverageOrderPerDay,
[Measures].[Orders Qty]
}
ON 0,
[Person].[PersonName].[PersonName].MEMBERS
* [Date Planned].[Week Of Year].[Week Of Year].MEMBERS ON 1
FROM [YourCube]

Related

MDX formatting results

I'm new to MDX querying. I am having trouble changing how the MDX output is formatted. I have made a similar example using the "Adventure Works Internet Sales Model". See below:
WITH
MEMBER [Measures].[Calculate YTD] AS
Sum
(
periodstodate([Date].[Calendar].[Year],[Date].[Calendar].CurrentMember)
,[Measures].[Internet Total Sales]
)
SELECT
{[Measures].[Internet Total Sales]
,[Measures].[Calculate YTD]
} ON COLUMNS,
[Date].[Calendar].[Month] ON ROWS
FROM [Adventure Works Internet Sales Model]
WHERE ([Date].[Date].&[2012-01-01T00:00:00]:[Date].[Date].&[2018-01-01T00:00:00])WHERE ([Date].[Date].&[2012-01-01T00:00:00]:[Date].[Date].&[2018-01-01T00:00:00])
the results looks like this:
MDX results
What I would like to see is that the "[Date].[Calendar].[Month]" row to be displayed as the end of month date (e.g. 31-Mar-2019)
Welcome to SO!
You could add in an additional column showing the last day of each month:
WITH
MEMBER [Measures].[Last Day of Month] AS
[Date].[Calendar].CurrentMember.LastChild.MEMBER_CAPTION
MEMBER [Measures].[Last Day of Month v2] AS
TAIL(EXISTING [Date].[Date].[Date].MEMBERS).ITEM(0).ITEM(0).MEMBER_CAPTION
MEMBER [Measures].[Calculate YTD] AS
Sum
(
periodstodate(
[Date].[Calendar].[Year],[Date].[Calendar].CurrentMember
)
,[Measures].[Internet Total Sales]
)
SELECT
{
[Measures].[Last Day of Month]
, [Measures].[Last Day of Month v2]
,[Measures].[Internet Total Sales]
,[Measures].[Calculate YTD]
} ON COLUMNS,
[Date].[Calendar].[Month]
ON ROWS
FROM [Adventure Works Internet Sales Model]
WHERE
(
[Date].[Date].&[2012-01-01T00:00:00]:
[Date].[Date].&[2018-01-01T00:00:00]
);
Output

Total is missing while create calculated measure using parallelperiod

Below is my query.
WITH
MEMBER [Measures].[Quantity - Prior Year] As
(
PARALLELPERIOD(
[Date].[Fiscal Year].[Fiscal Year]
, 2
, [Date].[Fiscal Year].CurrentMember
)
,[Measures].[Order Quantity]
)
SELECT
{
[Measures].[Order Quantity],
[Measures].[Quantity - Prior Year]
} ON AXIS(0)
, {DrilldownLevel([Date].[Fiscal])} ON AXIS(1)
FROM [Adventure Works]
CELL PROPERTIES VALUE, FORMAT_STRING, FORMATTED_VALUE
but the grand totals for calculated measure is always NULL?
Any help will be greatly appreciated.
It looks like "All Periods" is the system-generated All member for the [Date].[Fiscal Year] hierarchy.
From this Microsoft doc, it is the member with pre-aggregated measure values for all members in the [Date].[Fiscal Year] hierarchy. When this member is passed to the ParallelPeriod() function, it doesn't make sense to lag the aggregated value back 2 fiscal years, so it returns null.

MTD for current month in last year

How I can calculate MTD for current month in last year? Below query returns total [Net Sales Amount] for 12.2015, but need to have sales from 01.12.2015 to 09.12.2015(Today).
SUM(
MTD(
ParallelPeriod(
[Calender].[YMD].[Month],
12,
[Calender].[YMD].CurrentMember
)
)
,[Measures].[Net Sales Amount]
)
I think you need to use HEAD of the member you're finding:
SUM(
HEAD(
ParallelPeriod(
[Calender].[YMD].[Month],
12,
[Calender].[YMD].CurrentMember
).CHILDREN,
, 9
)
,[Measures].[Net Sales Amount]
)
The above is assuming that in the design of your cube Dates are the children of Month.
You need to make the 9 dynamic - do you have future dates in your cube?
If you do not have future dates then this could work:
WITH
MEMBER [Measures].[NumDaysInCurrentMonth] AS
Count(
Descendants(
TAIL([Date].[Calendar].[Month]).Item(0) //<<<not sure if Item(0) is required
,[Date].[Calendar].[Date]
,SELF
)
)
If you do have future dates then maybe the following:
WITH
MEMBER [Measures].[NumDaysInCurrentMonth] AS
count(
NONEMPTY(
Descendants(
TAIL([Date].[Calendar].[Month]).Item(0) //<<<not sure if Item(0) is required
,[Date].[Calendar].[Date]
,SELF
)
)
)
Then one of the above can feed into the previous:
WITH
MEMBER [Measures].[NumDaysInCurrentMonth] AS
COUNT(
Descendants(
TAIL([Date].[Calendar].[Month]).Item(0) //<<<not sure if Item(0) is required
,[Date].[Calendar].[Date]
,SELF
)
)
MEMBER [Measures].[PrevYearMTD] AS
SUM(
HEAD(
ParallelPeriod(
[Calender].[YMD].[Month],
12,
[Calender].[YMD].CurrentMember
).CHILDREN,
, [Measures].[NumDaysInCurrentMonth]
)
,[Measures].[Net Sales Amount]
)

MDX return last month of every year

I am trying to create a set to return the value of the last month that contains data for each year.
For example if I would put year on the rows
2011,2012,2013,2014 would all contain data for December.
2015 would contain data for June of 2015.
I can't seem to get anything but the latest month to return. I figure it is because of my tail statement, but I'm not sure how to fix it.
CREATE SET [Last Statement Month] AS
Tail(
nonempty(
Descendants(
[Date].[Calendar].currentmember
,[Date].[Calendar].[Month]
),
[Measures].[Sale Amount]
), 1);
I also tried to get the last day of each month, but when I use this with the year on the rows nothing shows up.
GENERATE(
{
Openingperiod([Date].[Calendar].[Month]):ClosingPeriod([Date].[Calendar].Month)
},
{[Date].[Calendar].CurrentMember.Lastchild}
);
I'm currently away from AdvWrks so unable to test. Does the following help?
CREATE SET [Last Statement Month] AS
TAIL(
NONEMPTY(
EXISTING ([Date].[Calendar].[Month].MEMBERS)
,[Measures].[Sale Amount]
)
);
(If this approach works) Performance is apparently better if EXISTING is performed last:
CREATE SET [Last Statement Month] AS
TAIL(
EXISTING
NONEMPTY(
[Date].[Calendar].[Month].MEMBERS
,[Measures].[Sale Amount]
)
);
Looks like the above isn't going to work. I've added an alternative in the following which maybe is more what you're looking for:
WITH
DYNAMIC SET [Last Statement Month] AS
Tail
(
NonEmpty
(
(EXISTING
[Date].[Calendar].[Month].MEMBERS)
,[Measures].[Internet Sales Amount]
)
)
MEMBER [Measures].[x] AS
[Last Statement Month].Item(0).Item(0).Member_Caption
MEMBER [Measures].[Lst mth with data] AS `<<<<maybe something like this helps?
Max
(
(EXISTING
[Date].[Calendar].[Month].MEMBERS)
,IIF
(
[Measures].[Internet Sales Amount] = 0
,NULL
/*,[Date].[Calendar].CurrentMember.Member_Caption*/ //<<WRONG PROPERTY USED
,[Date].[Calendar].CurrentMember.MemberValue //<<should help!!
)
)
SELECT
{[Measures].[Lst mth with data],[Measures].[x]} ON 0
,[Date].[Calendar].[Calendar Year] ON 1
FROM [Adventure Works];
Results in this:
After Edit returns this:

How to view the first and/or last member values in a hierarchy

Is there a way for me to view the first and/or last leaf value in a level of a hierarchy?
I am trying to create a calculation dimension in SSAS which will include, for example, a year to date calculation which I would prefer not to display for dates in the future.
I've worked out how to make that happen at the lowest level (date), but am getting errors ath te aggregation levels when trying to implement the technique.
To help me accomplish what I want I've included a [Date In Past] member in my dimension, which contains a 0 if the date is in the past, and a if it is not.
For example this query, which returns calculations by date:
with member [Measures].[Year To Date] as
Sum(
{ IIF(strtovalue(
[Time Order Date].[Date In Past].Currentmember.membervalue
) = 0, null, [Measures].[Product Rev (with ship, no disc)]
) } *
PeriodsToDate(
[Time Order Date].[Fiscal Date].[Fiscal Year Name],
[Time Order Date].[Fiscal Date].CurrentMember
)
)
select
{[Measures].[Product Rev (with ship, no disc)],
[Measures].[Year To Date]} on 0,
[Time Order Date].[Date].Children on 1
from [Sales Analysis]
returns nulls in the [Year to Date] measure for all dates in the future.
This query, which returns calculations by the week:
with member [Measures].[Year To Date] as
Sum(
{ IIF(strtovalue(
[Time Order Date].[Date In Past].Currentmember.membervalue
) = 0, null, [Measures].[Product Rev (with ship, no disc)]
) } *
PeriodsToDate(
[Time Order Date].[Fiscal Date].[Fiscal Year Name],
[Time Order Date].[Fiscal Date].CurrentMember
)
)
select
{[Measures].[Product Rev (with ship, no disc)],
[Measures].[Year To Date]} on 0,
[Time Order Date].[Fiscal Week Name].Children on 1
from [Sales Analysis]
returns errors for all of the [Year To Date] values, I assume because there are more than one member in the week.
I would like to compare it with the last day of the week. How can I do that?
Thanks, --sw
To answer your question literally: Yes, you can get the first or last member of a set, and hence of a level, using the Head and Tail methods. Just note that these return a one-element set, hence you would often use Tail(something).Item(0).Item(0) to get a member.
However, as I understand your question, what you really need is to know if in the currently context, the member [Time Order Date].[Date In Past].[a] exists.
In that case, I would use
with member [Measures].[Year To Date] as
IIf(Intersect(EXISTING [Time Order Date].[Date In Past].[Date In Past].Members,
{[Time Order Date].[Date In Past].[a]}
).Count = 1,
NULL,
Sum(PeriodsToDate([Time Order Date].[Fiscal Date].[Fiscal Year Name],
[Time Order Date].[Fiscal Date].CurrentMember
)
[Measures].[Product Rev (with ship, no disc)]
)
)
select
{[Measures].[Product Rev (with ship, no disc)],
[Measures].[Year To Date]} on 0,
[Time Order Date].[Fiscal Week Name].Children on 1
from [Sales Analysis]
EXISTING gets the set of all Date In Past members that exist in the current context. And the intersection of that with the one-element set of member a has either 1 element (if a is member of the first set), or 0 elements (in case a is not contained in the set), which explains the condition for the IIf.