MDX for calculated member with two measures over time hierarchy - sql-server

I have a cube with two measures, say Measure A and Measure B. I need to create a single measure say C, from these two based on the business rule at any level of the hierarchy,
If A is not empty at the current level (has value for all children at that level), then just aggregate A. Else, aggregate A wherever it is present and aggregate B wherever A is not present and then sum both to make C.
It goes like this
Quarter Month A B
Q1 Apr 2 3
Q1 May 4
Q1 Jun 4
C should be 10 at Quarter level. Also, 2 for Apr, 4 for May and 4 for Jun [Month level]
I used the following MDX which works fine at Month level.
IIF(IsEmpty([Measures].[A]), [Measures].[B], [Measures].[A])
But, at quarter level it just gives me 2 instead of 10 which I now know why :)
Any pointers on building a MDX to make it work at any level
[Year - Semester - Quarter - Month] (Granularity is at Month level only)
will be helpful. Thanks :)

You can use this Mdx
Sum(
Descendants('current member on your time hierarchy', 'month level'),
CoalesceEmpty([Measures].[A], [Measures].[B])
)
CoalesceEmpty([Measures].[A], [Measures].[B]) is equivalent to IIf(IsEmpty([Measures].[A]), [Measures].[B], [Measures].[A])

Related

Measure for a month and its previous using a named set SSAS

I have a named set that returns the last 10 weeks from the current week. In the cube browser I get the value of a measure for each week.
I want to create another measure that contains the value of the previous week returned by the named set. Something like this :
Weeks Measure1 Measure2
Week 1 50 40
Week 2 35 50
Week 3 77 35
How to do this using MDX ?
Measure2 will be a tuple of whatever measure you want to show - lets calls it [Measures].[Revenue] and the currentmember of the hierarchy used in the Weeks column lagged by 1.
I don't know the structure of your cube so you'll need to adjust the following:
(
[Measures].[Revenue],
[Date].[Calendar Week of Year].CURRENTMEMBER.LAG(1)
)

Cumulative Sum - Choosing Portions of Hierarchy

I have a bit of an interesting problem.
I required the cumulative sum on a set that is created by pieces of a Time dimension. The time dimension is based on hours and minutes. This dimension begins at the 0 hour and minute and ends at the 23 hour and 59 minute.
What I need to do is slice out portions from say 09:30 AM - 04:00 PM or 4:30PM - 09:30 AM. And I need these values in order to perform my cumulative sums. I'm hoping that someone could suggest a means of doing this with standard MDX. If not is my only alternative to write my own stored procedure which forms my Periods to date set extraction using the logic described above?
Thanks in advance!
You can create a secondary hiearchy in your time dimension with only the hour and filter the query with it.
[Time].[Calendar] -> the hierarchy with year, months, day and hours level
[Time].[Hour] -> the 'new' hierarchy with only hours level (e.g.) 09:30 AM.
The you can make a query in mdx adding your criteria as filter :
SELECT
my axis...
WHERE ( SELECT { [Time].[Hour].[09:30 AM]:[Time].[Hour].[04:00 PM] } on 0 FROM [MyCube] )
You can also create a new dimension instead of a hierarchy, the different is in the autoexists behaviour and the performance.

SSAS -> AdventureWorks Example -> Using the browser to splice a measure by week, shows results that have two of the same week records?

I have been working on a cube and noticed that when I am browsing measures in my cube by weeks, I am getting an unexpected result, but first let me display my current scenario. I am looking at counts of a fact load by weeks. When I do so I am getting results like these. :
Weeks | Fact Internet Sales Count
2001-07-01 00:00:00.000 | 28
2001-07-08 00:00:00.000 | 29
....and so on as you would expect.
Further down I noticed this. :
2001-09-30 00:00:00.000 | 10
2001-09-30 00:00:00.000 | 24
As you can see, it shows the week twice with different counts, when you add these counts together it is the correct number of counts for this week (i.e. 34).
I am just confused why it is showing two weeks, when I look at the data in sql I can see that the difference in data between these two is strictly the month in which these dates fell (10 in the earliest month and 24 and the later month in any example).
I initially saw this in my original cube that I created on my own, in turn, I pulled up trusty adventureWorks practice cube and found that it was present in that cube also.
This is due to the fact that within this date hierarchy, the lowest attribute in the hierarchy was date not week. Therefore, there was always a split for weeks by date. This can be alleviated by making a date hierarchy with week as the lowest portion of a date hierarchy.

How do I store (and sort) vague date ranges?

I have a database which needs to store year ranges (such as lifespan) which in some instances aren't very specific. For example, as well as the usual '1960', we have 'c. 1960' for "around 1960", and 1960s for in the decade 1960, as well as 'nd' for no date which is distinctly different from NULL which would be until present.
What would be the best way to store these?
I was thinking of possibly storing the year as a string and appending 's' for decades and 'c' for circa, with 'nd' for no date... but this feels just wrong. Also, when sorting chronologically I need to sort by inserting 1960s items before c. 1960 items, which in turn are before 1960 items.
How do I do this properly?
Some example date ranges:
1957
c. 1957
c. 1957 - 1965
c. 1957 - 1960s
c. 1957 - present
c. 1957 - nd
Thanks for your help!
You can insert the earliest and the latest date possible for the range.
Like, exact date will be
Jan 1, 1960 Jan 1, 1960
, c. 1960 will be
Jan 1, 1960 Dec 31, 1960
, 1960s will be
Jan 1, 1960 Dec 31, 1969
etc.
Then you can order by the first date and the datediff:
SELECT *
FROM mytable
ORDER BY
start_date, DATEDIFF(end_date, start_date) DESC
Alternatively, you can store the expected value and the deviation instead of the start and end dates.
This sounds like a 'fuzzy logic' type problem. I would tackle it by using multiple columns:
Earliest Possible date
Earliest Certain date
Latest Certain Date
Latest Possible Date
Your examples might be represented as
1957,1957,1957,1957
1955,1957,1957,1959
1955,1959,1965,1965
1955,1959,1960,1969
1955,1959,NULL,NULL
1955,1959,9999,9999
I'm assuming 'c' means +/-2 years, a decade runs from '0 to '9, and 9999 is a flag value for 'nd'
Any use?
I think Quassnoi answer is good, alternativly you could generate a time dimension then reference it in a simular way (though your dimention may not need as many rows)?
You need to predetermine what your circa structure is OR allow for varience. Circa is often associated with classification of artifacts (books, photo's, writings) and other entities (unknown exact birth/death dates) where wide varience might be found. Keep in mind that reclassification of artifacts often occurs as more information is gained. Thus what Max has defined works, but I would also add a definative classification date and perhaps a column with a description and/or name of the classifier/entity defining the classification. You can determine if you need historical records of reclassification and how to handle that.
One other item of note regarding things of this nature - what calendar was in place defining the actual date for a day such as the The date Oct 4 (Julian) was followed by the date Oct 15 (Gregorian) which was a change made in 1582 and the similar change in 1751 that change Britian and its then colonies to the Gregorian calendar. Thus you need to determine the calendar in use which can be translated to present day calendars.
The point of this, is you MIGHT also need an identifier of the calendar in use assiciated with the determination and cite that as well.
Additionally, some events are associated with months denoted as "first month, second month etc." which, might be confusing as for instance the Quakers change where "first month" in 1751 was March but in 1752 it was January - especially noted when genealogy is the subject matter (as you imply) and births/deaths are the events.
For fun, toss in Caeser and Calends (first day of March) and his reform of the leap year/day where February 24 was the leap day as "second 6th day preceding the Calends" so there were two February 24ths (two 6th days) in leap years.
I point this out because the number of days in a leap year may in some instances vary your periods.
So, use a structure such as Max and/or Quassnoi propose, but possibly a bit more for the deliniation.
Citation for calendars and understanding: What is a calendar
"How do I store (and sort) vague date ranges?"
(A) Let's analyze with an above-average level of scrutiny what it means to be a date range. This means that there is a precise start date and a precise end date of the range.
(B) Let's analyze with an above-average level of scrutiny what it might mean to be a "vague" date range. To me, it seems like this is some kind of date range in which either the start date, or the end date, or both, are not precisely known, but in which one (or both) of those are THEMSELVES a range.
(C) It is a known fact that the usual mathematical notion of "ordering" (aka "total order") does not usefully apply to the concept of "ranges" (how would you decide that 1-3 is either greater or smaller than 0-6 ?). It IS theoretically possible to define such an ordering, based on e.g. "order on start dates first, and within equal start dates, on end dates", but such an ordering is never useful.
(D) And if the "start date" and/or "end date" of a range are themselves "vague" (i.e. those components are ranges themselves), then it is obvious why it is insane to try and meaningfully order such ranges.
So the answer to the "(and sort)" part is : "You don't, because you can't (in a meaningful way)".

MDX, SSAS 2005 calculating SPLY (Same Period Last Year)

I'm trying to achieve the following: I have a measure: [Measures].[Sales] and a time dimmension: [Time].[Year - Month - Day]. I would like to add new measure: [Measures].[Sales SPLY] to work in the following way:
MONTH-----------------Sales--------------Sales SPLY
2009 January--------120 000,00--------110 000,00
2009 February ------100 000,00--------90 000,00
2009 March----------120 000,00--------110 000,00
TOTAL:---------------340 000,00--------290 000,00
The value of [Sales SPLY] is calculates using the following way: I created a new Sum measure, and in a Cube Script I replace it with the following code:
([Measures].[Sales SPLY], Leaves([Time])) = (PARALLELPERIOD([Time].[Year - Month - Day].[Year],1,[Time].[Year - Month - Day].currentmember), [MEASURES].[Sales])
It's working, however is just very, very slow. Does anyone know a better way of writing this MDX? using only the parrarel period in a calculated member will result in a bad value of the Total in SPLY measure. Please, I googled a lot and couldn't find any thing better than this.
I tend to just create a member like
WITH
MEMBER [Measures].[Sales SPLY] as ([Measures].[Sales], ParallelPeriod([Time].[Year - Month - Day].[Year],1,[Time].[Year - Month - Day].currentmember))
SELECT {[Measures].[Sales], [Measures].[Sales SPLY]} ON 0, ....
And it works fine.
How are you using it in your query overall?
Rob

Resources