Showing posts with label parallelperiod. Show all posts
Showing posts with label parallelperiod. Show all posts

Friday, March 23, 2012

ParallelPeriod: Same Day Last Month in long months

I am using the following MDX query to return same day last month values:

WITH

MEMBER [Measures].[Same Day Last Month] AS

'(ParallelPeriod([Reporting Date].[Year - Quarter - Month - Date].[Month],1),[Measures].[Active Account Indicator])'

SELECT

{[Measures].[Active Account Indicator],[Measures].[Same Day Last Month]} ON COLUMNS,

NON EMPTY {[Reporting Date].[Date].Members} ON ROWS

FROM [Financial]

This works for most days. However, for the last day of the month this cannot work when the current month has more days than the previous month. For example, on March 29, 30 and 31, the query will return NULL for [Same Day Last Month], since February 29, 30, 31 is an invalid date.

I am sure others have run into the same problem. What is the best way to solve this?

I'm grateful for any insights.

Dan

This could perhaps be more efficiently handled in scoped MDX script; but a recursive approach like this should work (except in the first month):

WITH

MEMBER [Measures].[Same Day Last Month] AS

iif(ParallelPeriod([Reporting Date].[Year - Quarter - Month - Date].[Month]) is null,

([Reporting Date].[Year - Quarter - Month - Date].PrevMember,

[Measures].[Same Day Last Month]),

(ParallelPeriod([Reporting Date].[Year - Quarter - Month - Date].[Month]),

[Measures].[Active Account Indicator]))

|||

Thank you, Deepak. I appreciate your response.

I believe I would have to use nested recursive statements for March 31. One month ago would indicate February 31, previous day would be February 30, and so forth until a valid date is reached.

However, this lead me to another solution which worked and follows our business rules: The last day of any month always contains values. Therefore, I was able to solve my problem using the following approach, employing the IsLeaf(), and the ClosingPeriod() function:

WITH

MEMBER [Measures].[Same Day Last Month] AS

'IIf(

--valtest

IsLeaf(

ParallelPeriod(

[Reporting Date].[Year - Quarter - Month - Date].[Month],

1

)

,

--valtrue

(

ParallelPeriod(

[Reporting Date].[Year - Quarter - Month - Date].[Month],

1

),

[Measures].[Active Account Indicator]

)

,

--valfalse

(

ClosingPeriod(

[Reporting Date].[Year - Quarter - Month - Date].[Date],

ParallelPeriod(

[Reporting Date].[Year - Quarter - Month - Date].[Month],

1

[Reporting Date].[Year - Quarter - Month - Date].CurrentMember.Parent

)

),

[Measures].[Active Account Indicator]

)

) --End IIf

'

SELECT

{[Measures].[Active Account Indicator],[Measures].[Same Day Last Month]} ON COLUMNS,

NON EMPTY {[Reporting Date].[Date].Members} ON ROWS

FROM [Financial]

ParallelPeriod, Subcubes, and SP2

We're defining some KPIs that include trend expressions which use the ParallelPeriod function to calculate the change in a KPI value since a past time period. For example, we calculate the change in the KPI value

When we use an MDX SELECT with a WHERE clause that specifies a time slice, the expression evaluates correctly.

However, when we use CREATE SUBCUBE to do the filter, or use BI Studio (which creates a subcube), the result is incorrect. In particular, the there's an IsEmpty check for the parallel period of the KPI value, so we're not doing bogus math when there's no data for the previous period. With the WHERE clause, that works fine, but with the subcube, the ParallelPeriod always evaluates to empty.

As a point of comparison, I tested with the Adventure Works cube, usign the "Internet Revenue" KPI, which includes a similar type of KPI trend (revenue for Current Time Member - Revenue for previous Fiscal Year). I see the same behavior there. This:
select
{KPIValue("Internet Revenue"), KPIGoal("Internet Revenue"), KPIStatus("Internet Revenue"), KPITrend("Internet Revenue")}
on columns
from
[Adventure Works]
where {[Date].[Fiscal Year].&[2004]}

returns 1 for the trend, but this:

CREATE SUBCUBE [Adventure Works] AS ( SELECT ( { [Date].[Fiscal Year].&[2004] } ) ON COLUMNS FROM [Adventure Works])

select
{KPIValue("Internet Revenue"), KPIGoal("Internet Revenue"), KPIStatus("Internet Revenue"), KPITrend("Internet Revenue")}
on columns
from
[Adventure Works]

returns 0.

So after lots of reading, I THOUGHT that SP2 fixed this problem. However, we installed the December CTP of SP2, and it doesn't seem to.Since subselects and CREATE SUBCUBE do not set current coordinate on non-aggregatable attributes, functions which look at them (such as ParallelPeriod, PrevMember, Lag, Parent, LastChild etc) won't apply. There were no change in SP2 in this respect. You can still use WHERE clause to set the current coordinate though.|||Ouch. I'm not sure how I came to believe this was being fixed in SP2.

Does Microsoft consider this a bug? Design limitation? Any plans to address it at some point?

Since we have no control over how query tools generate their MDX, it seems difficult to design a cube that uses these functions and have confidence that it will work correctly for our customers.|||

This is not a bug, but rather a design decision. Perhaps it can be reconsidered in the future versions. I don't know which tool you use, but at least Excel 2007 wihch makes extensive use of subselects, does use WHERE clause when the slice is a single member (and ParallelPeriod won't work on multi-select anyways).

HTH,

Mosha.

|||I was quite concerned about Excel 2007, as I saw lots of mentions that Excel uses subselects and subcubes out on the web. However, I did some quick testing, and as you say, it does seem to use the where clause in this case. That makes me feel a little better. Our QA people have mostly been testing with the BI Studio KPI browser so far, which exhibits the problem. The other client we need to test is Sharepoint 2007.

Can you share any insight about the rationale for SSAS work this way? In my Google I've seen numerous other people discussing this as a problem, so I hope MS seriously considers addressing it in a future release. We're trying very hard to stay query-tool agnostic in our designs - this definitely makes that more difficult.

Thanks,
Kevin|||

> In my Google I've seen numerous other people discussing this as a problem, so I hope MS seriously considers addressing it in a future release.

First, I do not use Google, I use Microsoft Live Search (www.live.com) instead. Subselects were originally designed to solve different class of problems, but the actual usage proved that people wanted to use them as more functionality rich WHERE clause, although we have tried to separate the functionalities of subselects and WHERE. This obviously didn't work out well, therefore SP2 brought many changes that made subselects and WHERE to be closer. It is correct to assume, that Microsoft seriously considers addressing this issue in the future release.

|||>First, I do not use Google, I use Microsoft Live Search
Naturally. But MS Live Search is so much harder to turn into a verb. ;)

>Microsoft seriously considers addressing this issue in the future release.

When you say "future release" - is this something that could theoretically be addressed in a service pack, were there sufficient demand? Or is it too significant a change for that, and we should expect to have to wait for the next full version of SSAS for a fix?

|||We never discuss the future plans or features that may be added in the future. All I said was that Microsoft is aware of the issue and seriously considers it. When and whether something will be done about it - is up to the product team, and will be disclosed through appropriate channels.|||

Thanks for the posting. I have been testing using both BIDS and the MOSS KPI webpart. For KPI's, BIDS implements an explicit CREATE SUBCUBE for slicing while Sharepoint 2007 seems to use an in-line subselect in the FROM clause to apply the selection from the filter webpart. In both cases a KPI based on a non-calculated measure works fine while any calculated measure based on a ParallelPeriod returns a null. Given the behavior in SP2 is there any available method for defining trend-type KPI's that depend on ParallelPeriod (or similar) functionality? Many of our KPI's depend on calculating the % change from the prior period.

Thanks

John

|||BIDS KPI browser is not end-user client tool, and therefore can be safely ignored here. As far MOSS KPI webpart, I suggest you report this issue to Sharepoint team, and ask them to use WHERE clause instead of subselect (or in addition to subselect if they choose so).|||

I have posted a question on the Sharepoint forum to ask about the KPI webpart.

As for BIDS, there's a point I don't understand. The profiler shows BIDS issuing a CREATE SUBCUBE statement as the slicer before the KPI query is excuted. We're using SQL Server 2005 SP2 and the updated BOL from December contains the following text in the description of the CREATE SUBCUBE statement:

"Also, explicit references to cells outside the subcube return cell values that are evaluated in the context of the whole cube. For example, you create a subcube that is limited to the current year. You then use the ParallelPeriod function to compare the current year to the previous year. The difference in values will be returned even though the previous year’s value lies outside the subcube."

Is this statement correct? Should a ParallelPeriod that defines a member outside the current context as specified by a CREATE SUBCUBE still return a value?

Thanks

|||Yes the statement in BOL is correct. The issue here is that subselect doesn't change current coordinate, so you are looking at ParallelPeriod of All member, which is NULL.

ParallelPeriod that never returns null

I'm sure this is easy, but I haven't been able to cook up the secret sauce: I need a function like ParallelPeriod that will always return a member (unless I'm asking for a member that predates the oldest member in the dimension, when null is perfectly fine).

For example, ParallelPeriod([Month],1,[2006].[December].[31]) returns null. Instead, I want to get back [2006].[November].[30] (the last day of the month).

What's the secret?

There are many ways to do it. One way is to have an attribute which keeps number of days needed to go back to get to the day in the previous month. Then you will use

Date.CurrentMember.Lag(Date.DaysToGoBack.MemberValue)

for December 30 it will be 30, and for December 31 it will be 31 - so both of them will land on November 30.

|||How 'bout a way that doesn't involve changing the definition of the cube?|||

Possible too, but it won't have as good performance as the solution I proposed first. Again, there are many ways, but they revolve around the following theme (note that the formula below is only valid for the Month level. I am not sure what you want to do on the other levels).

IIF(Date.CurrentMember IS Date.CurrentMember.Parent.LastChild, Date.CurrentMember.Parent.PrevMember.LastChild, ParallelPeriod(...))

|||

OK, I see the pattern. The solution you propose above won't quite work (think of March), but it's close enough to something that will work to see where to take it.

If I decide that I really need this function, I'll probably go with the first suggestion you made, since I can still change the cube design at this point, I was just looking for a wider variety of options.

Thanks for the suggestions!

Parallelperiod problem

Hi,

I tried to get last 52 weeks from the current period for LY sales.

We have fiscal date hierarchy (year - quarter - month -week) .

In scripts,

Paralleldate ( [date].[hierarchy].[year number], 1 , [date].[hierarchy].currentmember )

this works fine.

but

Scope([Date].[FISCAL YEAR NUMBER].members, [Date].[FISCAL MONTH NAME].members ,[Date].[FISCAL WEEK HISTORICAL NUMBER].members, [Date].[DATE KEY].members);

-- PRIOR YEAR CALCULATIONS

([Time Calculations].[Prior Year]=

(ParallelPeriod([Date].[Hierarchy].[Date].[Hierarchy].[FISCAL WEEK HISTORICAL NUMBER],52,

[Date].[Hierarchy].CurrentMember)

,[Time Calculations].&[ Current Period])

);

End Scope;

) ,

then it doesn't work. I don't know why. ( I can deploy the cube but when I browse the cube, it gives an error without any detailed info. )

FYI, we have fiscal week in historical number ( 52 weeks in fiscal yr) in date table.

then it doesn't work. I don't know why.

Please give me any comments.

A couple of clarifications:

- What is the purpose of this scope statement:

Scope([Date].[FISCAL YEAR NUMBER].members, [Date].[FISCAL MONTH NAME].members ,[Date].[FISCAL WEEK HISTORICAL NUMBER].members, [Date].[DATE KEY].members);

- Why is this assignment enclosed in parentheses:

([Time Calculations].[Prior Year]=

(ParallelPeriod([Date].[Hierarchy].[Date].[Hierarchy].[FISCAL WEEK HISTORICAL NUMBER],52,

[Date].[Hierarchy].CurrentMember)

,[Time Calculations].&[ Current Period])

);

|||

Sorry for the late response.

Now, we've just found some problems with perivios one, Due to the Hierarhcy attribute ( fiscal week key) we can't get last 52 weeks in time calculation called shell dimension.

But,

If I use time intelligence calculation wizard and change some for the prior year calcuation then the formula works fine only in week level .(please refer script as below)

I can't see values in year , quarter, and month levels ( these show 0 value), and in day level I can see the values but values are wrong.

To solve this problem and to view prior year value in all levels( y- q- m -w- day) , how can I approach ?

It seems this formula only works for week level values.

Thank you in advance and please give me any comments.

--Scripts for prior year--

(

[Date].[Fiscal Hierarchy Date Calculations].[Prior Year],

[Date].[FISCAL WEEK HISTORICAL NUMBER].[FISCAL WEEK HISTORICAL NUMBER].Members,

[Date].[Tbl DIM Date].Members

) =

Aggregate(

{ [Date].[Fiscal Hierarchy Date Calculations].DefaultMember } *

{

ParallelPeriod(

[Date].[Fiscal Hierarchy].[FISCAL WEEK],

52,

[Date].[Fiscal Hierarchy].CurrentMember

) : [Date].[Fiscal Hierarchy].CurrentMember

})

- Aggregate(

{ [Date].[Fiscal Hierarchy Date Calculations].DefaultMember } *

{

ParallelPeriod(

[Date].[Fiscal Hierarchy].[FISCAL WEEK],

51,

[Date].[Fiscal Hierarchy].CurrentMember

) : [Date].[Fiscal Hierarchy].CurrentMember

}

);

sql

ParallelPeriod over a set?

Classic multi-select problem. I am trying to display the delta between visits to our clinic for the current timeframe versus the same timeframe last year. Pretty straightforward application of ParallelPeriod.

The following query works just fine:
WITH
MEMBER [Measures].[Test] AS
'[Measures].[Visits] - (ParallelPeriod([Time].[Visit Date].[Year], 1), [Measures].[Visits])'

select
{[Test], [Visits]} on columns
from [Clinic]

where ([February 2006])

However, change the where clause to include a set rather than a member...
WITH
MEMBER [Measures].[Test] AS
'[Measures].[Visits] - (ParallelPeriod([Time].[Visit Date].[Year], 1), [Measures].[Visits])'

select
{[Test], [Visits]} on columns
from [Clinic]

where ({[February 2006], [March 2006]})


...and it breaks with the following error: #Error The MDX function PARALLELPERIOD failed because the coordinate for the 'Quarter' attribute contains a set.


Thanks to Moshe's very useful article on multi-select (http://sqljunkies.com/WebLog/mosha/archive/2005/11/18/multiselect_friendly_mdx.aspx), I understand what is going on. Since I am selecting a set rather than a single member from the visit date hierarchy, parallelperiod chokes.

WHERE I NEED HELP:
What I would like to be able to do is apply parallelperiod to each member of the set and aggregate the result. As I understand it, that would fix my problem and, I believe, give me the correct result. However, I'm not yet good enough at MDX to figure out how to do this. Help, please?


Here is an example using Adventure Works and the "Existing" operator to sum the total for whatever months are contained in your WHERE clause set:

Original Query

WITH

MEMBER [Measures].[Test] AS

[Measures].[Order Count] - (ParallelPeriod([Date].[Calendar].[Calendar Year], 1), [Measures].[Order Count])

SELECT

{[Measures].[Test], [Measures].[Order Count]} on columns

FROM

[Adventure Works]

WHERE

([Date].[Calendar].[Month].&[2004]&[1])

Revised Query using Existing

WITH

MEMBER [Measures].[Test] AS

SUM(Existing [Date].[Calendar].[Month].Members,

([Measures].[Order Count] - (ParallelPeriod([Date].[Calendar].[Calendar Year], 1), [Measures].[Order Count])))

SELECT

{[Measures].[Test], [Measures].[Order Count]} on columns

FROM

[Adventure Works]

WHERE

({[Date].[Calendar].[Month].&[2004]&[1],

[Date].[Calendar].[Month].&[2004]&[2]})

HTH,

Steve

Wednesday, March 21, 2012

ParallelPeriod MDX function not working

I created a calculated measure called [Previous Year Percent Rejected]. I used the following expression:

(ParallelPeriod([Year],1,[Time].[Time Hierarchy].CurrentMember),[Measures].[Percent Rejected])

The syntax checks out fine. However, when I try to use the calculation, I get an error message -- with a #VALUE! in the column.

The error message reads " The parallel period expression expects a level expression for the argument. A hierarchy expression was used."

I tried many different variations but I'm always receiving the same message. Any suggestions?

David

If you're using AS 2005, the problem could be that there is also an attribute hierarchy associated with [Year]. So, you could try fully specifying the [Year] level, like:

(ParallelPeriod([Time].[Time Hierarchy].[Year],1,[Time].[Time Hierarchy].CurrentMember),[Measures].[Percent Rejected])

|||

Thank you Deepak. Your solution fixed the problem.

David

ParallelPeriod Error

I keep getting an error "The ParallelPeriod function expects a member expression for the argument. A tuple set expression was used." Is there something that I can use instead of LastPeriods to get this to work?

Here is the trend expression for a KPI that I get the error for:

(KPIVALUE('ABI Aggregate Test')-(CoalesceEmpty(

Aggregate({[Entities].[SITE].&[1]}

* {[Entities].[EntityType].[Site]}

* {[TDVs].[Parameter - Material].&[Bitum_Coal_Usage_Site -]}

* {ParallelPeriod([Date].[Year - Quarter - Month - Date].[Date], 1,

LastPeriods(3, StrToMember('[TDV Result Date].[Year - Quarter - Month - Date].[Year].[Calendar ' + EssMdx.Ess.Epm.AnalysisServices.MdxFunctions.Timeframe.GetLastFullYear() + ']')))}

, [Measures].[Result]),0)))

Could you describe what you are trying to do? It looks like you are trying to go back 1 day from a set consisting of the last 3 years. If you are trying to compare the KPI value to the same day 3 years ago you could use the Lag() function instead of LastPeriods(), but I don't really think that is what you are trying to do.|||

Sorry, the above line {ParallelPeriod([Date].[Year - Quarter - Month - Date].[Date], 1, should be {ParallelPeriod([Date].[Year - Quarter - Month - Date].[Year], 1,

I am trying to get a trend expression based on 1 year back (or 2 or 3...). ParallelPeriod has been working fine except with date ranges. The KPI value expression will give me a value for the last 3 full years (2006, 2005, and 2004) and is the same expression without the ParallelPeriod function. If the trend is 1 year back then it should be 2005, 2004, and 2003 (or it may be 2003, 2002, 2001).

Thanks

|||

That makes a bit more sense. In this case you simply have the LastPeriods and ParallelPeriod function nested the wrong way around, changing it to the following should work. Basically you need to pass the result of your GetLastFullYear Function to ParallelPeriod() and then pass the member from that to LastPeriods.

eg

(KPIVALUE('ABI Aggregate Test')-(CoalesceEmpty(

Aggregate({[Entities].[SITE].&[1]}

* {[Entities].[EntityType].[Site]}

* {[TDVs].[Parameter - Material].&[Bitum_Coal_Usage_Site -]}

* {LastPeriods(3,
ParallelPeriod([Date].[Year - Quarter - Month - Date].[Date], 1,StrToMember('[TDV Result Date].[Year - Quarter - Month - Date].[Year].[Calendar ' + EssMdx.Ess.Epm.AnalysisServices.MdxFunctions.Timeframe.GetLastFullYear() + ']')))}

, [Measures].[Result]),0)))

|||Thanks.

ParallelPeriod Calculated Member - Don't want to tie to year

I currently have Calculated Member in a cube that shows ParallelPeriod using a hierachy based off the year. So you always get prior year amounts, even while drilling into the hierarchy. Here is this Calculated Member (nothing special). This takes the amount you are on and subtracts the previous years amount.

Code Snippet

[Measures].[Amount] - ([Measures].[Amount], ParallelPeriod([Date].[Year - Quarter - Month].[Year], 1, [Date].[Year - Quarter - Month].CurrentMember))

What I am looking to do is always show the prior period based on where you are in the hierarchy (and do it with one calculated member). So I want to take amount and subtract it by the previous period based on where you are in the hierachy (Q2 2007 - Q1 2007, and not Q2 2007 - Q2 2006). This would be an example.

Hierarchy is Year - Quarter - Month. When looking at Years, you see previous year....when you drill into Quarter, you see the previous Quarter of the same year (so you see Q2, 2007 compared to Q1, 2007 and not Q2, 2006). And so on.

Hope that makes sense. Any help is greatly appreciated.

Would PrevSibling be applicable here.

Steve

|||Try [Measures].[Amount] - ([Measures].[Amount], [Date].[Year - Quarter - Month].PrevMember)
|||

Jeffrey Wang wrote:

Try [Measures].[Amount] - ([Measures].[Amount], [Date].[Year - Quarter - Month].PrevMember)

This seems to work. I knew it was something straightforward. Thank you very much for your help!