I am trying to create a dynamic named set that can be used in slicing data using date dimension. I want to have a several named set something like last day, last 7 days, last month, last quarter and so on. For "last day" named set, i am thinking of doing something like.
StrToMember("[Date].[Calendar].[Day].&[" + DateAdd("d", -1,Tail( [Date].[Calendar].[Day], 1) + "]")
I want DateAdd("d", -1, Tail( [Date].[Calendar].[Day], 1) + "]") to return the member_value so that i can build the uniquename string to return a member, is it possible?
The reason why I am using DateAdd is that, sometimes I am having a gap in my data for Day level, so using previousmember will sometimes return a wrong data.
Ps: What I meant for the last day is not actually equal to function Now()-1, it is the last day that is available in the cube, that is why I cannot depend on the servers system time to achieve this.
This will hopefully give you the last day:
WITH
MEMBER [Date].[Calendar].[LastDay] AS
Tail([Date].[Calendar].[Day]).ITEM(0).ITEM(0)
SET [VariousDates] AS
{[Date].[Calendar].[LastDay]}
SELECT
[VariousDates] ON 0
FROM [MyCube]
You can then create more members in the set [VariousDates]:
WITH
MEMBER [Date].[Calendar].[LastDay] AS
Tail([Date].[Calendar].[Day]).ITEM(0).ITEM(0)
MEMBER [Date].[Calendar].[Last7Days] AS
AGGREGATE(
Tail(
[Date].[Calendar].[Day]
,7
)
)
SET [VariousDates] AS
{
[Date].[Calendar].[LastDay]
,[Date].[Calendar].[Last7Days]
}
SELECT
[VariousDates] ON 0
FROM [MyCube]
(above not tested but hopefully helps)
Related
I have a SSAS cube with the following dimensions:
Time
DayName <- Hierarchy
Item
Description <- Hierarchy
In the Measures dimension I have a measure for the LostAmount.
I want to query the cube so that I can get the sum of lost amount per week day. The following query works:
select
except(Time.DayName.members, {Time.DayName.[All]}) on 0,
except(Item.Description.members, {Item.Description.All}) on 1
from Cube
But when returning the results the order of columns is not the natural order of week days (i.e. the order of columns is Friday, Monday, Sunday etc).
How can I have the result columns in the natural order of week days i.e. Monday, Tuesday etc.?
If you look at your screenshot, the days in the Time.DayName level are being sorted in natural order: it's the alphabetical order of the member names.
There's no way that SSAS can "know" what the order you want is. I'd suggest adding a Key column to this dimension, numbering the days in the order you want, and changing the dimension attribute's OrderBy property to Key rather than Name. (Perhaps you already do have a key: but OrderBy=Name will naturally order the members by their name).
Addition: There is a dimension attribute Type property in SSAS, which can be set to "Day of Week" - but I've never used it, and don't know whether it would correctly detect that your member names are the names of weekdays. Or whether it will order your week starting on the "right" day that you want to start your week from. You could try setting it and seeing what happens.
While it's definitely better to change the cube structure, sometimes it's not a feasible option. In such cases, it has to be handled inside MDX code(which is slower). Below is one way.
WITH
MEMBER measures.weekdaynumber AS
CASE Time.DayName.CURRENTMEMBER
WHEN "Monday" THEN 1
WHEN "Tuesday" THEN 2
WHEN "Wednesday" THEN 3
WHEN "Thursday" THEN 4
WHEN "Friday" THEN 5
WHEN "Saturday" THEN 6
WHEN "Sunday" THEN 7
END
SELECT
Order
(
Except
(
Time.DayName.MEMBERS
,{Time.DayName.[All]}
)
,Measures.weekdaynumber
) ON 0
,Except
(
[Item].[Description].MEMBERS
,{[Item].[Description].[All]}
) ON 1
FROM [Cube];
I have found a workaround for the ordering issue by defining additional members on the Measures dimension and outputting them in the desired order:
with
member Measures.Monday as
sum(Time.DayName.&[Monday], Measures.LostValue)
member Measures.Tuesday as
sum(Time.DayName.&[Tuesday], Measures.LostValue)
member Measures.Wednesday as
sum(Time.DayName.&[Wednesday], Measures.LostValue)
member Measures.Thursday as
sum(Time.DayName.&[Thursday], Measures.LostValue)
member Measures.Friday as
sum(Time.DayName.&[Friday], Measures.LostValue)
member Measures.Saturday as
sum(Time.DayName.&[Saturday], Measures.LostValue)
member Measures.Sunday as
sum(Time.DayName.&[Sunday], Measures.LostValue)
select
{
Measures.Monday,
Measures.Tuesday,
Measures.Wednesday,
Measures.Thursday,
Measures.Friday,
Measures.Saturday,
Measures.Sunday
} on 0,
except(Item.Description.members, {Item.Description.[All]}) on 1
from [Cube]
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]
I'd like an easy way of getting the total number of days for each month in the date dimension.
Currently this information is not exposed in our cubes. Therefore I need to write custom mdx such as the following:
WITH
SET [13Mth] AS Tail([Date].[Date - Calendar Month].[Calendar Month].MEMBERS ,13)
SET [m] AS Tail([13Mth])
MEMBER [Measures].[TotalNumDaysMth] AS
Datepart
("D",
Dateadd
("M",1,
Cdate(Cstr(VBA!Month([m].Item(0).Item(0).Lag(1).Name)) + "-01-" + Cstr(VBA!Year([m].Item(0).Item(0).Lag(1).Name)))
)
- 1
)
MEMBER [Measures].[TotalNumDaysMth-1] AS
Datepart
("D",
Dateadd
("M",1,
Cdate(Cstr(VBA!Month([m].Item(0).Item(0).Lag(1).Name)) + "-01-" + Cstr(VBA!Year([m].Item(0).Item(0).Lag(1).Name)))
)
- 1
)
I don't believe our users will need this information within our cube browsing client but from a developer point of view I could do without having to always implement the above.
What approach should we use to make the above data more easily available?
I have always added an attribute to the date dimension "days in month", of type integer. You can hide this attribute, if you do not want to expose the attribute hierarchy to your users.
But you can still use in calculations.
So my advise would be add a proper attribute to your time dimension and base your calculations of on the attributes.
Hope this helps somehow.
I am assuming that in your development scenario, the month will come from Web Service/Front End/SSRS report etc. In any such cases, you can create a measure that will return the count.
Approach 1: Year-Quarter-Month-Date exists
It is a good practice to have a similar hierarchy in place. The following MDX will work:
with set CurrentMonth as
[Date].[Year-Quarter-Month-Date].currentmember
set DatesInCurrentMonth as
descendants(abc, [Date].[Year-Quarter-Month-Date].[Date])
member [Measures].countofdaysinmonth as
count(DatesInCurrentMonth)
select measures.CountOfDaysInMonth on 0
from [MyCube]
where [Date].[Year-Quarter-Month-Date].[Month].&[Feb-2004]
Approach 2: Such hierarchy doesn't exist
with set CurrentMonth as
[Date].[Month].currentmember
set DatesInCurrentMonth as
exists([Date].[Date].children, abc, "<<Any Measure group>>")
member measures.countofdaysinmonth as
count(DatesInCurrentMonth)
select measures.countofdaysinmonth on 0
from [MyCube]
where [Accident Date].[Month].&[Feb-2004]
Let me know if they work/have issues.
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.
I'm building a report in Reporting Services 2005 based on a SSAS 2005 cube. The basic idea of the report is that they want to see sales for this fiscal year to date vs. last year sales year to date. It sounds simple, but being that this is my first "real" report based on SSAS, I'm having a hell of a time.
First, how would one calculate the current fiscal year, quarter, or month. I have a Fiscal Date Hierarchy with all that information in it, but I can't figure out how to say: "Based on today's date, find the current fiscal year, quarter, and month."
My second, but slightly smaller problem, is getting last years sales vs. this years sales. I have seen MANY examples on how to do this, but they all assume that you select the date manually. Since this is a report and will run pretty much on it's own, I need a way to insert the "current" fiscal year, quarter, and month into the PERIODSTODATE or PARALLELPERIOD functions to get what I want.
So, I'm begging for your help on this one.
You'll probably need to modify the SSRS MDX by hand to do this. It is possible to get SSAS to use "Today", it is usually done as something like this:
WITH
MEMBER [Today]
AS {
StrToMember("[Date].[Date Key].&[" + Format(now(), "yyyyMMdd") + "]")
}
SELECT
[Measures].[Some Measure]
ON COLUMNS
FROM
[Cube]
WHERE
{[Today]}
You'll need to change that to fit your own cube structure of course.
So, given that you have fiscal year, and you want to plug values in, modify the above to fit? Put together a string like I showed you that equates to the values you want to use. It sounds like you're OK after that?
You should be able to figure this out using various functions which can tell you 'where you are in the hierarchy'
e.g.
http://www.sqldev.org/sql-server-analysis-services/find-parent-of-current-day-10080.shtml
I know it is a "bit" too late but for people reaching this question page this might help:
IIF(Month(Now()) > MonthOffSetNumber, Year(Now()) + 1,Year(Now()))
This is for getting the current fiscal year. This will be applied in something like this:
SET CurrentFiscalYear AS
(
StrToSet("[Dim Date Name].[Fiscal Year].&[" + Format(IIF(Month(Now()) > MonthOffSetNumber, Year(Now()) + 1,Year(Now()))) + "]")
)
This will help for later cross join in the query.
WE find an easy way to calaculate fiscal period to date date in mdx by using parameters. Imagine that we have BeginDate (01/04/2014) and EndDate (31/03/2015). Here are the formulars. Click on Parameter "beginDate" in Report Data - right click parameters - Specify values - add expression value:
=DATEADD
("M"
,IIF(Month(Today())<4
,-Month(Today())-8
,-Month(Today())+4
)
,DATEADD("D",0-DATEPART("D",Today())+1,Today()))
Do the same for the second parameter "EndDate" and set the Defualt values - Specify values and add expression value:
=DATEADD("D",-1,DATEADD("M",12,DATEADD
("M"
,IIF(Month(Today())<4
,-Month(Today())-8
,-Month(Today())+4
)
,DATEADD("D",0-DATEPART("D",Today())+1,Today()))))
Now your ssrs report will have the fiscal period as default period.
Moise Kabongo