Count Working Days MDX - ssas

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:

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

MDX queries in SSMS vs calculated membersin cubes performance

I have some MDX queries with calculated members than when I run them in SSMS run very fast.
But when I implement these calculated members in the cube and run them, it's very slowly.
Any ideas of this behavior?
This is the query that runs smoothly in SSMS, but it takes forever when I query the cube from Excel or Tableau (against the same calculated members in the Cube)
with member [Measures].[Sales BUM Avg 3Months]
as
sum(
lastperiods(3, ancestor([Date].[Calendar].currentMember,[Date]. [Calendar].[Calendar Year Month])), [Measures].[Sales Month BUM]
)
/
count(
nonempty(lastperiods(3, ancestor([Date].[Calendar].currentMember,[Date].[Calendar].[Calendar Year Month])), [Measures].[Sales Month BUM])
)
member [Measures].[CoverageSalesBUM]
as
sum([Measures].[Unrestricted BUM])
/
sum([Measures].[Sales BUM Avg 3Months] )
select non empty { [Measures].[Unrestricted BUM] , [Measures].[Sales BUM Avg 3Months] } on 0
,non empty([Date].[Calendar].[Calendar Date] , [Plant].[Plant].[Plant],[Material].[Material].[Material].[149249] ) on 1
from [InventCoverage]
(More of a code review than an answer, as I don't know much about cube scripts so cannot comment on what you might need to do to the cube)
Is you first calculation not a re-invention of the function Avg?
Also in you second calc why do you need to apply Sum()? If this is the aggregation set in the cube then no need to explicitly say Sum. Also apparently Divide is quite a recent introduction and maybe marginally more efficient
WITH
MEMBER [Measures].[Sales BUM Avg 3Months] AS
Avg
(
LastPeriods
(3
,Ancestor
(
[Date].[Calendar].CurrentMember
,[Date].[Calendar].[Calendar Year Month]
)
)
,[Measures].[Sales Month BUM]
)
MEMBER [Measures].[CoverageSalesBUM] AS
Divide
(
[Measures].[Unrestricted BUM]
,[Measures].[Sales BUM Avg 3Months]
)
SELECT
NON EMPTY
{
[Measures].[Unrestricted BUM]
,[Measures].[Sales BUM Avg 3Months]
} ON 0
,NON EMPTY
(
[Date].[Calendar].[Calendar Date]
,[Plant].[Plant].[Plant]
,[Material].[Material].[Material].[149249]
) ON 1
FROM [InventCoverage];

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 count YTD days in my MDX query

I've below MDX query which gives me YTD amount for each my device perfectly, but I want count of those YTD days taken in consideration while calculating YTD amount.
How can I achieve those YTD days counts in my query?
WITH
MEMBER [Settlement Date].[Calendar].[CalendarYTD] AS
Aggregate
(
YTD
(
[Settlement Date].[Calendar].[Settlement Calendar Month].&[201412]
)
)
SELECT
[Settlement Date].[Calendar].[CalendarYTD] ON COLUMNS
,NON EMPTY
[Device].[DeviceID].Children ON ROWS
FROM [cube1]
WHERE
[Measures].[amount];
OR
you can use below AW MDX query while making changes which give same results as my above query:
WITH
MEMBER [Date].[Calendar].[CalendarYTD] AS
Aggregate(YTD([Date].[Calendar].[Month].[March 2015]))
SELECT
[Date].[Calendar].[CalendarYTD] ON COLUMNS
,[Product].[Category].Children ON ROWS
FROM [Adventure Works]
WHERE
[Measures].[Order Quantity];
this is a little swapped around but hopefully heading in the direction you require:
WITH
MEMBER [Date].[Calendar].[CalendarYTD] AS
Aggregate(YTD([Date].[Calendar].[Month].[March 2007]))
MEMBER [Measures].[DaysCompleteCurrYear] AS
Descendants
(
YTD([Date].[Calendar].[Month].[March 2007])
,[Date].[Calendar].[Date]
,SELF
).Count
SELECT
{
[Measures].[DaysCompleteCurrYear]
,[Measures].[Order Quantity]
} ON COLUMNS
,[Product].[Category].Children ON ROWS
FROM [Adventure Works]
WHERE
[Date].[Calendar].[CalendarYTD];
If we put the target month into a single member set then the family relationships are preserved and we can use that set in the custom measures:
WITH
SET [targMth] AS
{[Date].[Calendar].[Month].[March 2007]}
MEMBER [Date].[Calendar].[CalendarYTD] AS
Aggregate(YTD([targMth].Item(0).Item(0)))
MEMBER [Measures].[DaysCompleteCurrYear] AS
Descendants
(
YTD([targMth].Item(0).Item(0))
,[Date].[Calendar].[Date]
,SELF
).Count
SELECT
{
[Measures].[DaysCompleteCurrYear]
,[Measures].[Order Quantity]
} ON COLUMNS
,[Product].[Category].Children ON ROWS
FROM [Adventure Works]
WHERE
[Date].[Calendar].[CalendarYTD];

SSAS - Sum of Top or Bottom

SELECT
[Measures].[Internet Sales Amount] ON COLUMNS
,Tail
(
[Date].[Calendar Year].[Calendar Year].MEMBERS
,2
) ON ROWS
FROM [Adventure Works];
Above MDX query gives me output as :
Year Internet Sales Amount
CY 2003 $9,791,060.30
CY 2004 $9,770,899.74
I understood how this query worked but I want to create Calculated measure in a cube which will always give me sum of bottom 2 years. How to do this? I am a newbie to SSAS. I am good at designing simple measures and dimensions but when it comes to using MDX, I am mostly stuck.
PS: I tried using TopCount, BottomCount etc but here I want to order by "Year", which is a dimension.
Any help would be appreciated.
Thanks,
Parry
The following query calculates a measure for sum the the last 2 years of the Date dimension:
WITH
MEMBER [Measures].[Sales from the last 2 Years]
AS Aggregate( Tail( [Date].[Calendar Year].[Calendar Year].Members, 2)
, [Measures].[Internet Sales Amount]
)
SELECT { [Measures].[Sales from the last 2 Years]
} ON COLUMNS
, { Tail( [Date].[Calendar Year].[Calendar Year].Members, 2)
} ON ROWS
FROM [Adventure Works]
Other interesting query, would be calculating a measure for the sum of each year and its previous:
WITH
MEMBER [Measures].[Sales from 2 years]
AS Aggregate( { [Date].[Calendar Year].CurrentMember.PrevMember
: [Date].[Calendar Year].CurrentMember }
, [Measures].[Internet Sales Amount]
)
SELECT { [Measures].[Internet Sales Amount]
, [Measures].[Sales from 2 years]
} ON COLUMNS
, NON EMPTY
{ [Date].[Calendar Year].[Calendar Year]
} ON ROWS
FROM [Adventure Works]
It does a sum, because the aggregation type of the measure [Measures].[Internet Sales Amount] is Sum, and the Aggregate function aggregates according to the measure's aggregation type.
Key Concepts in MDX
Aggregate function reference
MDX is a hard topic to grasp; if you're starting out, I recommend you read the book MDX Solutions, 2nd edition.