MDX / Analysis Services Calculating Month To Date - mdx

I don't usually get involved with MDX if I dont have to, but....
I have a cube with simple fact table linked to a time dimension (with date,month,year columns and so on) and I want to be able for a given day of the month calculate the month to date total for that day.
In SQL it would be a doddle, however I'm not sure of how to achieve this in MDX.
Update I have an example working for a fixed date. Now I want to know how to do this for any possible date
WITH
MEMBER MTD_15_Feb_2010 AS
Aggregate
(
MTD([Date].[Year Name - Quarter Name - Month Name - Name].[Name].[02/15/2010]),
[Measures].[Value]
)
SELECT
{
MTD_15_Feb_2010
} ON 0
FROM [Cube]

You should be able to create the MDX using the MTD function. It will return the set of all days from the first of the month up to the member passed to the function.
Edit: There are multiple ways to update your example for any day. I would suggest replacing the date member [02/12/2010] with the CURRENTMEMBER function. This would also allow you to display the value for multiple dates as in the example below.
WITH MEMBER [MTD_Value] AS AGGREGATE (
MTD([Date].[Year Name - Quarter Name - Month Name - Name].[Name].CURRENTMEMBER)
, [Measures].[Value]
)
SELECT [MTD_Value] ON 0
, {
[Date].[Year Name - Quarter Name - Month Name - Name].[Name].[02/15/2010]
, [Date].[Year Name - Quarter Name - Month Name - Name].[Name].[01/15/2010]
, [Date].[Year Name - Quarter Name - Month Name - Name].[Name].[02/15/2009]
} ON 1
FROM [Cube]

Related

multidimensionel cube: sum on filtered fact

I have a fact_dueAnalysis table which contains all my customers outstanding. The table is built with a Date Reporting, so when I pick a specific Date Reporting date, I can see all customers outstanding for that specific day.
Now I want to let my users use a date hierarchy so they can select e.g. week 39 and get all outstanding for the LAST day of that week (I will always use the last date in the hierarchy my users have selected).
I have made the following script:
([Measures].[Due Amount],[Date Reporting].[Year - Week - Date].[Week].members) =
sum(generate(tail(
DESCENDANTS([Date Reporting].[Year - Week - Date].[Week],, leaves),1),1
)
,[Measures].[Customer Due Amount]);
I am here trying to get the latest (tail) date (leave) on my Date Reporting and then sum the Customer Due Amount and get the result in a new measure called Due Amount.
When the users select a specific date, it does work, but when they select a week I get a #VALUE as result.
How should I create this correct?
Here is my end result:
([Measures].[Due Amount],[Date Reporting].[Year - Week - Date].[Week].members) =
SUM(TAIL(DESCENDANTS([Date Reporting].[Year - Week - Date].CURRENTMEMBER,
[Date Reporting].[Year - Week - Date].[Date]),1)
,[Measures].[Customer Due Amount]);
This will do what I want:
Get the latest date in a selected week and sum the Customer Due Amounts and present it as Due Amount.

MDX - Calculated MTD measure returning null value

I have a Cube with a Date dimension hierarchy (Year,Semester,Quarter,Month,Day).
There are 2 measures available in the datawarehouse.
[AUD DLY] : Daily numbers
[AUD YTD] : Daily incremental YTD numbers
Hierarchy is as follows
Date - Dimension
Financial - Hierarchy
Year - [Date].[Financial].[Year]
Semester - [Date].[Financial].[Semester]
Quarter - [Date].[Financial].[Quarter]
Month - [Date].[Financial].[Month]
Day - [Date].[Financial].[Day]
Measures [AUD DLY]
Measures [AUD YTD]
I need to add a MTD field in the measures such that when the business select a particular date on their slicer in excel for e.g., 3 March 2016, MTD should be calculated as either of the following ways :
1) [AUD MTD] should be calculated by subtracting [AUD YTD] on
last day of previous month from the current selected date.
So if we select 3 March 2016 then
[AUD MTD] = [AUD YTD] on 3 March 2016 - [AUD YTD] on 29 Feb 2016
OR
2) [AUD MTD] should be calculated by adding the [AUD DLY] from first day
of the current month until the selected date in that month.
So if we select 3 March 2016 then
[AUD MTD] = SUM ([AUD DLY] from 1 March 2016 to 3 March 2016)
I created a New Calculated Member from Calculations tab in the Cube designer in the BIDS 2010. The MDX query is below. However when I try to browse the cube the [AUD MTD] values are only returning nulls.
Can someone please help what am I doing wrong ?
CREATE MEMBER CURRENTCUBE.[Measures].[AUD MTD]
AS Aggregate
(
PeriodsToDate
(
[Date].[Financial].[Month]
,[Date].[Financial].CurrentMember
)
,[Measures].[AUD DLY]
),
FORMAT_STRING = "Currency",
NON_EMPTY_BEHAVIOR = { [AUD DLY] },
VISIBLE = 1 , DISPLAY_FOLDER = 'AUD Values' , ASSOCIATED_MEASURE_GROUP = 'Measures' ;
Also the business would be using the new calculated measure in excel using the Slicer, they want to select any date and be able to view the MTD value for that month.
Also can someone please help with MDX query for both methods (1) and (2) ?
Your help much appreciated.
I think the problem with your quoted code (method 2) is that [Date].[Financial].CurrentMember must be at a level at or below the [Date].[Financial].[Month] level. Otherwise PeriodsToDate returns an empty set.
So the problem is not in your calculated member definition, but somewhere in the query in which it's being used. In that query, [Date].[Financial].CurrentMember may be returning a member at a level above Months. Hard to see without seeing the query itself.
Method (1) is more fiddly. You can get the last day of the previous month with
Ancestor([Date].[Financial].CurrentMember,[Date].[Financial].[Month]).PrevMember.LastChild
but you'd have to build in some logic for days in the first month of the financial year, which would otherwise subtract the value for a previous fin year from this year's YTD value. So I'd recommend method (2).
As far as I know selecting a date (I mean a date, not a month) in the Excel slicer will make that date the .CurrentMember. I'm a bit hesitant because Excel does generate some deeply bizarre MDX sometimes.
EDIT: Another possible problem is a hierarchy mismatch. You can select a perfectly good Day in a date hierarchy, but if it isn't in exactly the hierarchy you specify in your calculated member definition, you can get weird results. IMHO more recent versions of SSAS encourage a proliferation of attribute hierarchies and multiple "real" hierarchies, making this a real problem.
As a test can you please add this very simple measure to make sure that currentmember is behaving as expected:
CREATE MEMBER CURRENTCUBE.[Measures].[AUD MTD]
AS [Date].[Financial].CurrentMember.member_caption
If when you use the above all it returns is the All member then you know something is wrong.
You need to double-check your relationships and datatypes used within your date hierarchies as this is often the reason for time calculation problems.
This is an alternative to your measure but I suspect if the original script is not working then neither will this...
CREATE MEMBER CURRENTCUBE.[Measures].[AUD MTD]
AS SUM
(
MTD([Date].[Financial].CurrentMember)
, [Measures].[AUD DLY]
)

MDX to calculate difference between sales amount between 2 dates

I have a Cube with a Date dimension hierarchy (Calendar,Year,Month,Week,Day) and Measure as SalesData, would like to add a calculated measure which would give me the SalesData for the selected date and the last date of the Previous Month.
Calendar Hierarchy is as follows
Date - Dimension
Calendar - Hierarchy
Year - [Date].[Calendar].[Year]
Quarter - [Date].[Calendar].[Quarter]
Month - [Date].[Calendar].[Month]
Week - [Date].[Calendar].[Week]
Day - [Date].[Calendar].[Day]
Measures
[Sales]
New Calculated Member need to be created - say [SalesMTD]
Requirement is when a user select any date say 3 March 2016, the calculated member should give Sales as follows
[SalesMTD] = [Sales] on 3 March 2016 - [Sales] on 29 Feb 2016
Can someone please help me write an MDX query for the Calculated Measure ?
Your help much appreciated.
Please try the below code.
CREATE MEMBER CURRENTCUBE.[Measures].[Sales Last Month]
AS ([Date].[Months].CURRENTMEMBER.PREVMEMBER, [Measures].[sales])
, VISIBLE = 1 ;
Then write another calculation using the above calculations
CREATE MEMBER CURRENTCUBE.[Measures].[Sales Difference]
AS ([Measures].[Revenue]-[Measures].[Sales Last Month])
, VISIBLE = 1 ;
with member measures.SalesDataLastDaylasMonth
as
[Date].[Calendar].currentmember.firstsibling.lag(1)
//or [Date].[Calendar].currentmember.firstsibling.prevmember
select {measures.SalesData, measures.SalesDataLastDaylasMonth} on 0,
[Date].[Calendar].[Day].members on 1
from [Some Cube]
Here currentmember.firstsibling.prevmember fetches the member prior to the first day in the list of days in the current month.
Also, you can obviously create this member in a cube instead of having it query scoped like this. The syntax would be similar to the above answer.
Based upon your edit
There are multiple ways of getting to it. Below are some:
with member Measures.[SalesMTD]
as
Measures.[Sales]
-
(Measures.[Sales],Ancestor([Date].[Calendar].currentmember, [Date].[Calendar].[Month]).firstchild.firstchild)
//(Measures.[Sales],[Date].[Calendar].currentmember.parent.parent.firstchild.firstchild.lag(1))
//(Measures.[Sales],[Date].[Calendar].currentmember.parent.parent.firstchild.firstchild.prevmember)
select Measures.[SalesMTD] on 0,
[Date].[Calendar].[Day].members on 1
from [Some Cube]
The first approach is the neatest.

PPS 2010 YTD vs. calculated measure aggregation fails (with pics)

I have 2 measures:
Sales Value
Sales Value LY (calculated measure)
and a time filter with single month member and YTD formula.
If i make simple PerformancePoint report like so:
It shows up correctly like this when single month is selected from the time filter:
But when i try the YTD formula from the time filter:
the calculated measure is lost from the report.
Any ideas?
I would try to change the ParallelPeriod(Month, 12) to ParallelPeriod(Year, 1) in your measure definition:
scope ({Measures.[Sales Value LY]});
this = (PARALLELPERIOD(
[Time].[Year - Month - Date].[Year],
1,
[Time].[Year - Month - Date].CURRENTMEMBER
),
[Measures].[SALES AMOUNT]);
end scope;
ParallelPeriod only works properly if the current period is below or at the level stated as the first argument.
EDIT
Maybe changing the expression like proposed at http://sqlblog.com/blogs/mosha/archive/2007/01/13/multiselect-friendly-mdx-for-calculations-looking-at-current-coordinate.aspx would help:
scope ({Measures.[Sales Value LY]});
this = Sum(EXISTING [Time].[Year - Month - Date].[Day].Members,
(PARALLELPERIOD(
[Time].[Year - Month - Date].[Year],
1,
[Time].[Year - Month - Date].CURRENTMEMBER
),
[Measures].[SALES AMOUNT]
)
);
end scope;
I was guessing the name of your day level, maybe you have to adapt that.
Have a workaround thus:
built-in YTD semiadditive function in PPS time intelligence can be written also like this:
year.firstmonth.parent:year.month.parent
Dunno if the YTD function is buggy or whatnot, but this was the quick way to get the parallel YTD values..

Using the ANCESTOR function on a DATE dimension

Here is my script:
WITH MEMBER [Date].[Date - Calendar Month].[2MthPrev] AS
(
ANCESTOR(
CLOSINGPERIOD([Date].[Date - Calendar Month].[Calendar Month]),
2
))
SELECT
NON EMPTY
{
[Date].[Date - Calendar Month].[2MthPrev]
}
ON ROWS,
NON EMPTY
[Measures].[Revenue]
ON COLUMNS
FROM [OurCube]
The query runs with no error but the result pane is empty.
I've attempted to create a custom member in the [Date - Calendar Month] hierarchy that is two months previous to the last month in the hierarchy's level [Calendar Month]. So if the last loaded month in the cube is July 2013 then I'd hope that [2MthPrev] would show the results from May 2013.
I believe the problem is with the custom member [2MthPrev] and its use of ANCESTOR - how is this fixed?
This query returns 2 months prior from the last populated date for the given measure group. You may have to fiddle with it to make a calculated member. The second argument in tail is optional. If you don't include it, the default value is 1.
So I'm returning the item that is 2 prior to (lag) the first item (Item(0)) of the set which includes the last month (tail) from the set of months for which there are values in the Measure Group (exists clause).
select {Tail(Exists([Date].[Date - Calendar Month].[Calendar Month].members, , "Measure Group Name")).Item(0).lag(2)} on 0
from [OurCube]
Not sure to understand the query but assuming [Calendar Month] is having at most 2 levels (ALL + months) I guess you're asking for something like :
[a-month].parent.parent = [all].parent = null
[2MthPrev] is a scalar value and not a member; if you want to debug to sth like:
with [2MthPrev] as ancestor( ... ).uniqueName
Hope that helps.