Return the last non empty member of date dimension, based on other dimension - mdx

New to MDX and a bit bewildered...
We have a cube with an excel pivot table over the top for reporting. What I need to provide is an easy means for people to see the max (last) member of the relevant date dimension when also sliced against another dimension, and the row count on that day.
I have a "booking count" measure and I want to see the number of bookings on the last date I had any bookings for any other dimensions children. If that makes sense.
The closest i've got so far is this:
select [Measures].[Booking Count] on 0, filter(([Sub Channel].[Channels].[Channel].members, [Booking Date].[Date].children), not isempty([Measures].[Booking Count])) on 1 from myCube
But I can't then use LastChild or similar to get the last member of each channel.
Hope that makes sense! Huge thanks in advance for any help.

You are nearly there, just use the Tail function to get the last date from your set:
select [Measures].[Booking Count]
on 0,
Tail(filter(([Sub Channel].[Channels].[Channel].members, [Booking Date].[Date].children),
not isempty([Measures].[Booking Count])))
on 1
from myCube

Related

Calculated measure to find the datediff using timedimension

I need to find out the number of days in Month based on Time dimension. Time dimension is Month when Jan is selected it has to return 31 as value.
If you have Time dimension and Time hierarchy, this should work:
WITH MEMBER measures.NumOfDays AS
Count
(
Descendants
(
[Time].[Time].CurrentMember,
,LEAVES
)
)
SELECT Measures.NumOfDays ON 0,
[Time].[Time].Month on 1
FROM [MyCube]
The below sample shows how to get the count.
Please note the below query only show the idea how to do this. Your cube will note have these attributes you you need to replace them
with member
measures.t as Count(([Date].[Month of Year].&[1],[Date].[Day of Month].[Day of Month].members))
select {measures.t}
on columns
from [Adventure Works]

MDX: Make Measure Value 0 based on flag

Would much appreciate any help on this.
I have a measure called "Sales" populated with values, however i am trying to turn the "Sales" value to 0, whenever the "Sales Flag" is set to 0.
Important Note: The Sales Flag is based on Date (lowest level of detail).
The difficulty that i am really experiencing and cant get a grip on, is how i am trying the display the MDX outcome.
As explained above, i would want to make the "Sales" value 0 whenever we have a 0 in the "Sales Flag" (which is based on the Date), but when I run the MDX Script I would wan't on the ROWS to NOT display the Date, but instead just the Week (higher Level to Date), as below shows:
I really have spent hours on this and can't seem to understand how we can create this needed custom Sales measure based on the Sales Flag on the date level, but having the MDX outcome display ROWS on Week level.
Laz
You need to define the member in the MDX before the select. Something like that:
WITH MEMBER [Measures].[Fixed Sales] as IIF([Sales Flag].currentMember=1,[Sales], 0)
SELECT [Measures].[Fixed Sales] on 0, [Sales Flag] on 1 from [Cube]
I am writing the code without SSAS here so it might not be the 100% correct syntax but you can get the general idea ;)
You can add the iif in the SELECT part but I find creating member to be the cleaner solution.
SELECT IIF([Sales Flag].currentMember=1,[Sales], 0) on 0, [Sales Flag] on 1 from [Cube]
If you have a control over the cube in SSAS you can create a calculated member there and you can access it easier.
Glad to hear if Veselin's answer works for you, but if not...
Several approaches are also possible.
Use Measure expression for Sales measure:
Use SCOPE command for Day level (if it's Key level of Date dimension). If it's not a key level you have to aggregate on EVERY level (week, year etc) to emulate AggregateFunction of Sales measure but with updated behavior for one flag:
SCOPE([Date].[Your Date Hierarchy].[Day].members,[Measures].[Sales]);
THIS=IIF([Sales Flag].CurrentMember = 1,[Measures].[Sales],0);
END SCOPE;
Update logic in DSV to multiply Sales column by SalesFlag. This is the easiest way from T-SQL perspective.

How to filter time hierarchy based on anothr attribute's value in MDX

I want to create a calculated member. I have a time dimension hierarchy" YQM", which has Year/Quarter/Month. The calculated member should find YTD till the current month. However, the value of current month will come from database.
I have created a attribute, "CP" which returns the current month value.
Please tell me how to create the calculated member. Please note "CP" is not in the same hierarchy YQM.
I don't understand why you are using Aggregate. So, I will assume that it is there for some purpose, which you have't clarified. Now, if the members of [YQM].[Month] and [Dim].[CP] are of the same format, then you can try the code below:
Aggregate(
PeriodsToDate([Dim].[YQM].[Month].MEMBERS,
FILTER([Dim].[YQM].[Month].MEMBERS,
[YQM].[Month].CURRENTMEMBER.member_value = [Dim].[CP].FirstChild.member_value)
)
)
Why not try playing with the function YTD. The following should give you the monthly amount in the first column of data and then the YTD amount in the next column:
WITH MEMBER [Measures].[YearToDate] AS
AGGREGATE(
YTD()
,[Measures].[someMeasureInCube]
)
SELECT
{
[Measures].[someMeasureInCube],
[Measures].[YearToDate]
} ON 0,
[Dim].[YQM].[Month].MEMBERS ON 1
FROM [yourCube]

MDX Select measures between two values

I have a fact table which stores for each record an init_year and end_year as integers, which refer to the year range in which the record is valid.
In which way I can design a MDX query to select my measures (count) for each year, in order to have a trend of my measures over year?
THANKS
I'm not sure this should be done in MDX.
This sort of thing is usually calculated in the fact tables (linked to a dimension table of all available years), and a new measure is created. No calculation would be done in MDX; you'd just display the new measure.
Having said that, I've just Googled "MDX count start end date" and found www.purplefrogsystems.com/blog/2013/04/mdx-between-start-date-and-end-date which suggests you use the LINKMEMBER function. Their example code was...
AGGREGATE(
{NULL:LINKMEMBER([DATE].[Calendar].CURRENTMEMBER
,[START DATE].[Calendar])}
* {LINKMEMBER([DATE].[Calendar].CURRENTMEMBER
, [END DATE].[Calendar]):NULL}
, [Measures].[Project COUNT])
...or...
AGGREGATE({NULL:[DATE].[Calendar].CURRENTMEMBER}
, [Measures].[Project COUNT])
...but it needs careful reading!

Filtering a Dimension Relative to a CurrentMember in MDX

I'm having a bit of trouble accomplishing something that I think should be relatively straightforward in MDX. I would like to create a calculated member that provides a sum of one of my measures over the previous two weeks at a given point in time. My time dimension looks like:
TimeId TradingDate Day of Week
-----------------------------------
1000 11/1/2012 Thursday
1001 11/2/2012 Friday
1002 11/5/2012 Monday
1003 11/6/2012 Tuesday
... ...
What makes this particularly difficult is that my Time dimension is not quite complete. The members of my Time dimension only correspond to trading days in the stock market, and not all time. This means that weekends, holidays, or any other day in which the stock market is closed are excluded. This also means the normal methods of traversing time such as LAG or PARALLELPERIOD will not work quite right here. LAG(14), for example, means "14 trading days", which at any given point could represent a variable length of actual time.
Inside my calculated member, I'm attempting to use FILTER in order to get only time members that are within the previous two weeks of the CurrentMember. However, I can't seem to figure out the proper syntax (if there is one) to accomplish this. I imagine it would be something like:
WITH MEMBER [Sum of Price Previous 2 Weeks] AS
SUM(
FILTER(
[Time].[TimeId].Children
, [Time].[TradingDate].MemberValue
>= VBA!DATEADD("ww", -2, [Time].[TradingDate].CurrentMember.MemberValue)
)
, [Price]
)
However, this doesn't quite work. I can't seem to separate the context of the calculated members current iteration from what would be a separate context inside of the FILTER function. In other words, I'm not sure how to say:
"When iterating over the set inside of FILTER, compare the current
member of each iteration against the value of the CurrentMember in
the scope of the calculated member"
Is what I'm trying to accomplish even possible? Is there a different approach I could be taking to accomplish what I'm after?
The result you'll get from a calculated member will depend on the axis of your query. So first, make sure you have [Time].[TradingDate] in your axis.
Second, your [Time].[TradingDate] hierarchy should be ordered by Key (I assume TradingDate is the key).
Now you can use this member definition:
WITH MEMBER [Sum of Price Previous 2 Weeks] AS
SUM(
[Time].[TradingDate].CurrentMember.Lag(14):[Time].[TradingDate].CurrentMember, [Price]
)
You can use set aliases to refer to the outer CurrentMember in the Filter context:
WITH MEMBER [Sum of Price Previous 2 Weeks] AS
SUM(
GENERATE([Time].[TradingDate].CurrentMember AS CurrentDateAlias,
FILTER(
[Time].[TimeId].Children
, [Time].[TradingDate].MemberValue
>= VBA!DATEADD("ww", -2, CurrentDateAlias.Item(0).MemberValue)
)
)
, [Price]
)
GENERATE is used just to define the alias somewhere.