MDX return last month of every year - ssas

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:

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

I'm stuck with MDX query

i need sales amount of first month of each quarter
WITH SET [FIRSTMONTHOFQTR] AS
DESCENDANTS(
DESCENDANTS(
[Date].[Calendar].CURRENTMEMBER,
[Date].[Calendar].[Calendar Quarter]
),
[Date].[Calendar].[Month]
)
SELECT {
[Measures].[Sales Amount]
} ON COLUMNS,
{
[FIRSTMONTHOFQTR]
} ON ROWS
FROM [Adventure Works];
With above im getting each month but i need only first month. how can i filter that?
This is one approach:
WITH
SET [Qtrs] AS
[Date].[Calendar].[Calendar Quarter]
SET [FIRSTMONTHOFQTR] AS
Generate
(
[Qtrs] AS s
,Head(Descendants(s.CurrentMember,[Date].[Calendar].[Month]))
)
SELECT
{[Measures].[Sales Amount]} ON COLUMNS
,[FIRSTMONTHOFQTR] ON ROWS
FROM [Adventure Works];
It returns the following:

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.

Count Working Days MDX

I would like to count the working days of a spesific time range and then find the Average Daily Dispatches.Currently the time range is at WHERE statement.
I believe that I have include the date range in the 1st Member but I can't figure how to count the dates in a month range.
Any suggestments?
WITH MEMBER [Measures].[Working Days] AS
COUNT(Date.[Working Date].&[1])--Doesn't work
MEMBER [Measures].[Average Daily Dispatches] AS
[Measures].[Total Dispatches]/[Measures].[Working Days]
SELECT [Measures].[Average Daily Dispatches] ON 0
FROM [cube]
WHERE (
[Date].[Month].&[2015-01-01T00:00:00]:[Date].[Month].&[2015-08-01T00:00:00]
);
Use the NonEmpty function to yield those working dates on which there was a dispatch. Then use COUNT on top of this.
WITH MEMBER [Measures].[Working Days] AS
COUNT
(
NonEmpty
(
[Date].[Working Date].MEMBERS,
[Measures].[Total Dispatches]
)
)
Some sort of alternative seems to exist using Exists/Existing (I think 1 is Monday in the AdvWrks cube!)
WITH
MEMBER [Measures].[MondayCnt] AS
Count
(
Exists
(
(EXISTING
[Date].[Calendar].MEMBERS)
,[Date].[Day of Week].[1]
)
)
MEMBER [Measures].[Averge] AS
[Measures].[Internet Sales Amount] / [Measures].[MondayCnt]
SELECT
{
[Measures].[Internet Sales Amount]
,[Measures].[MondayCnt]
,[Measures].[Averge]
} ON 0
,
[Date].[Calendar].[Month].&[2006]&[6]
:
[Date].[Calendar].[Month].&[2007]&[6] ON 1
FROM [Adventure Works];
The above results in the following:

Create Set to get Last month of Each Year

I would like to create a set that returned the last Date for each year. For example all previous years would return December, but the current year would only return the current month.
WITH
SET testset AS
NonEmpty
(
Generate
(
{
OpeningPeriod([Date].[Calendar].[Month])
:
ClosingPeriod([Date].[Calendar].Month)
}
,{[Date].[calendar].CurrentMember}
)
,[Measures].[Sale Amount]
)
SELECT
NON EMPTY
(
[Measures].[Sale Amount]
,[Date].[Year].[Year]
) ON 0
,NON EMPTY
[testset] ON 1
FROM [Cube]
Here is an example of a script that returns the values for each month. I've tried using tail and lastchild, but that only returns the most recent. I would like it to return for every Year.
In terms of just the last month - ignoring whether there is data for it or not the following:
WITH
SET [AllYears] AS
[Date].[Calendar].[Calendar Year].MEMBERS
SET [LastMths] AS
Generate
(
[AllYears] AS S
,Tail
(
Descendants
(
S.CurrentMember
,[Date].[Calendar].[Month]
)
,1
)
)
SELECT
{} ON 0
,[LastMths] ON 1
FROM [Adventure Works];
Returns this:
If I want to adapt the above so that it is the last month per year that has data for a specific measure then wrap NonEmpty around the set created by Descendants:
WITH
SET [AllYears] AS
[Date].[Calendar].[Calendar Year].MEMBERS
SET [LastMths] AS
Generate
(
[AllYears] AS S
,Tail
(
NonEmpty //<<new
(
Descendants
(
S.CurrentMember
,[Date].[Calendar].[Month]
)
,[Measures].[Internet Sales Amount] //<<new
)
,1
)
)
SELECT
{} ON 0
,[LastMths] ON 1
FROM [Adventure Works];
It now gives us this:
We can then add in the tuple you have on rows (I have used the attribute hierarchy this time for years as [Date].[Calendar] is already in use)
WITH
SET [AllYears] AS
[Date].[Calendar].[Calendar Year].MEMBERS
SET [LastMths] AS
Generate
(
[AllYears] AS S
,Tail
(
NonEmpty
(
Descendants
(
S.CurrentMember
,[Date].[Calendar].[Month]
)
,[Measures].[Internet Sales Amount]
)
,1
)
)
SELECT
NON EMPTY
(
[Measures].[Internet Sales Amount]
,[Date].[Calendar Year].[Calendar Year]
) ON 0
,[LastMths] ON 1
FROM [Adventure Works];
Now we get this:
#Whytheq has already given a very good solution. Treat this as an alternative. This might be a tad faster as it doesn't use the GENERATE function (not sure though!).
Have a calculated/cube measure which basically tells whether a month is the last month of the year. Then select those months out of the set of months.
with member measures.islastchild as
iif
(
[Date].[Calendar].currentmember is
[Date].[Calendar].currentmember.parent.parent.parent.lastchild.lastchild.lastchild,
1,
null
)
The member measures.islastchild returns 1 if the month is the last month of the year. Else it would return null.
set lastmonths as
filter(
[Date].[Calendar].[Month].members,
measures.islastchild = 1
)
The set lastmonths is then the set you need.
edit
To further improve the performance, you can NonEmpty function instead of the iterative FILTER function.
set lastmonths as
NonEmpty(
[Date].[Calendar].[Month].members,
measures.islastchild
)
select lastmonths on 1,
{} on 0
from [Adventure Works]
EDIT 2: To get the last non month with sales
with member measures.islastnonemptychild as
iif
(
[Date].[Calendar].currentmember is
TAIL(NonEmpty([Date].[Calendar].currentmember.parent.parent.parent.lastchild.lastchild.children, [Measures].[Sale Amount])).ITEM(0),
1,
null
)
set nonemptylastmonths as
NonEmpty(
[Date].[Calendar].[Month].members,
measures.islastnonemptychild
)