MDX Full Last year (not to date) - ssas

I use this for LastYTD
ROUND(
SUM(YTD(ParallelPeriod([Invoice Date].[Date Hierarchy].[Year]
, 1
, [Invoice Date].[Date Hierarchy].CurrentMember))
, [Measures].[Revenue]
),
2
)
Now I need full last year, not YTD. How to do that?
UPDATE:
II have tried following but it shows results only on Year level.
ROUND(
SUM(YTD(ParallelPeriod([Invoice Date].[Date Hierarchy].[Year]
, 1
, ClosingPeriod([Invoice Date].[Date Hierarchy].[Year],
[Invoice Date].[Date Hierarchy].CurrentMember)
)
)
, [Measures].[Revenue]
),
2
)
SCREENSHOT
Query 2:
ROUND(
SUM(ParallelPeriod([Invoice Date].[Date Hierarchy].[Year]
, 1
, [Invoice Date].[Date Hierarchy].CurrentMember)
, [Measures].[Revenue]
),
2
)
Results:
UPDATE3:
This is what I need:

I was able to do this with 2 calculations
CREATE MEMBER CURRENTCUBE.[MEASURES].[Revenue FY]
AS SUM((ANCESTOR([Date].[Y-Q-M-D].Currentmember, [Date].[Y-Q-M-D].[Year])), [Measures].[Revenue]),
FORMAT_STRING = "#,#",
VISIBLE = 1 ;
CREATE MEMBER CURRENTCUBE.[MEASURES].[Revenue FY LY]
AS (PARALLELPERIOD( [Date].[Y-Q-M-D].[Year], 1,[Date].[Y-Q-M-D] ),[Measures].[Revenue FY]),
FORMAT_STRING = "#,#",
I hope this can help you.

ROUND(
SUM(ParallelPeriod([Invoice Date].[Date Hierarchy].[Year]
, 1
, [Invoice Date].[Date Hierarchy].CurrentMember)
, [Measures].[Revenue]
),
2
)
I have just removed YTD function from your expression. On my DB this expression works fine, except the situation when we have some gaps in the date dimension (for example: 2009, 2011 members exist on level Year, but not 2010 member).
/**********************************/
Updated version:
(by the comments: all members for the current year must contain value for the previous year)
(
ClosingPeriod(
[Invoice Date].[Date Hierarchy].[Year]
,[Invoice Date].[Date Hierarchy].CurrentMember
).lag(1)
, [Measures].[Revenue]
)
p.s. This expression hasn't been tested yet.

Related

MDX Query to get Last Year data without filtering based on current month

i have been doing a query to get previous year value in MDX but can't the the desired output. In sql i would do it like this. Question is how do i apply this query in MDX?
select data1, sum(data2) as sumthisyear, sumlastyear
from table1 a
left outer join
( select data1, sum(data2) 'sumlastyear'
from table1
where tableyear = 2017 group by data1
) b on a.data1 = b.data1
where tableyear= '2018' and datafilter = 'SampleFilter'
group by data1, sumlastyear
SSAS Cube Structure Image
I have done some research and did mdx function like parallelperiod but not giving the correct values as data are filtered based on 2018 year.
Here's my MDX query
CREATE MEMBER CURRENTCUBE.Measures.[SPLY Registered Sales] AS
iif( [DimProdDate].[Dates].CurrentMember Is
[DimProdDate].[Dates].[All].LastChild,
( PARALLELPERIOD( [DimProdDate].[Dates].[Calendar Year],
1,
Tail( NonEmpty( [DimProdDate].[Dates].[Full Date].MEMBERS,
[MEASURES].[Registered Sales]),
1
).Item(0)
),
[MEASURES].[Registered Sales] ),
( PARALLELPERIOD( [DimProdDate].[Dates].[Calendar Year],
1,
[DimProdDate].[Dates].CurrentMember
),
[MEASURES].[Registered Sales] )
);
Any help will be very much appreciated.
Thanks!

MDX Calculation speed - CurrentMember?

I am still getting to grips with MDX and I am looking for some help. Here is my MDX query:
CREATE MEMBER CURRENTCUBE.[Measures].[Fake]
AS
IIF(
(
(
[Sales Data].[Ship-to No].CurrentMember
,[Sales Data].[Price Type].&[Core]
,[Measures].[Sales - Local Currency]
)
/ (
[Sales Data].[Ship-to No].CurrentMember,
[Sales Data].[Price Type].[(All)].[ALL],
[Measures].[Sales - Local Currency]
)
) > 0.9
,1
,NULL
),
VISIBLE = 1;
CREATE MEMBER CURRENTCUBE.[Measures].[Test Calc]
AS
SUM(
Descendants(
[Sales Data].[Ship-to No].CurrentMember
,[Sales Data].[Ship-to No].[Ship-to No]
),
[Measures].[Fake]
),
VISIBLE = 1;
SalesData is the fact table and the basic calculation is to count the number of customers that have sales of more than 90% of the price type "Core".
The query currently takes around 5 seconds to complete but I think this can be faster if I don't use CurrentMember according to http://sqlblog.com/blogs/mosha/archive/2008/07/29/product-volatility-optimizing-mdx-with-mdx-studio.aspx
But I don't know where to begin in changing this, can anyone help me make this more efficient?
If you delete currentmember from the first measure does it make any difference?
CREATE MEMBER CURRENTCUBE.[Measures].[Fake]
AS
IIF(
(
(
[Sales Data].[Price Type].&[Core]
,[Measures].[Sales - Local Currency]
)
/ (
[Sales Data].[Price Type].[(All)].[ALL],
[Measures].[Sales - Local Currency]
)
) > 0.9
,1
,NULL
),
VISIBLE = 1;
In respect of the currentmember you use in the second measure maybe EXISTING will suffice:
CREATE MEMBER CURRENTCUBE.[Measures].[Test Calc]
AS
SUM(
EXISTING [Sales Data].[Ship-to No].[Ship-to No].MEMBERS
,[Measures].[Fake]
),
VISIBLE = 1;

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

Calculating Avg Orders per day using MDX

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]

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.