0
votes

I've been working in an OLAP cube as a pivottable in excel for a while now, but more recently I'm trying to integrate some calculated measures to streamline some things, and I've hit a wall.

The cube has date filters set up that specify the month & year (they get more specific, but finer levels aren't used).

The rows will list individual projects, and the values can reflect 2 measures: one that reflects the average score for the date range, and another that reflects the number of observations the average is based on.

I would like to create a calculated measure that will display the average score for each project as long as 2 criteria are met:

  1. There is a minimum of 100 observations for the whole date range
  2. there are no months with zero observations across the date range specified in the pivottable.

I should also clarify that the date ranges I use will vary and length, and will not always end with the most recent month, but they will always be in increments of whole months.

I'm part of the way there, as a calculated measure based on this will provide me with the average only if there are enough observations for the date range:

IIF([Measures].[OBSERVATIONS]>=100,[Measures].[AVERAGE],"^^")

Now, I need to add the criteria of no months with zero observations.

I have attempted to use COUNT(), but in this form it ignores the date range set in the pivottable and returns a count of all of the months there is any value for the project, including zeros.

COUNT(([Calendar].[Calendar].[Month],[Measures].[OBSERVATIONS]),EXCLUDEEMPTY)

I tried determining the lowest number of observations in a month using this expression, but again it ignores the date range, and does not reflect empty cells:

MIN([Calendar].[Calendar].[Month],[Measures].[OBSERVATIONS])

I think CurrentMember is what I need to include, but I can't get it to work for me.

Assuming it's relevant, and I'm not sure the best way to explain the calendar hierarchy, so this reflects what I have:

OLAP Cube calendar

The first calendar listing is the one used to filter the pivot table data, and it is also pulled into the mdx expressions above.

EDIT:

Thanks @SouravA for the reply. I tried a few things, and given that formatting in comments is limited, here's a rundown of what I did.

I'm getting an error message that says "Query(1,35) Parser: The syntax for 'WITH' is incorrect"

to make sure I'm using this correctly:

After making the changes below, I pasted the whole thing into the MDX: window from the 'calculated measures' tool in Excel.

I of course changed OBSERVATIONS and AVERAGE to the variable names in my cube.

I changed '[Project].[ProjectCode]' to '[Project].[ProjectName]', which is how my cube is set up.

On '[NewMeasure]' I changed it to the name I am using for the calculated measure.

on '[your cube]' I've tried a couple different things; the cube reference I use in the cube formulas in excel looks like this: 'Cubename NormativeCube', so I tried pasting that in the brackets with and without quotes, leaving the NormativeCube part off, and doing all that without the brackets.

I also modified the last line after 'WHERE' to reflect date ranges like this: '[Calendar].[Calendar].[Month].&1&[2015]:[Calendar].[Calendar].[Month].&[12]&[2015]'

I've also set that as '[Calendar].[Month].[Month].&1:[Calendar].[Month].[Month].&[12]'

Also, one more question; will this work for any date range, or is it intended to be specified in the MDX? I need it to function based on the date range set by the cube filters.

EDIT 2:

I just needed to tweak this a tad by changing the '> 0' to '= 0', as the original solution only showed the average for those that did not have data for each month in the date range, and adjust one of the calendar set expressions or whatever.

IIF
 (
  [Measures].[OBSERVATIONS]>=100 
  AND 
  COUNT
    (
     FILTER
        (
        EXISTS
            (
            [Calendar].[Calendar].[Month].MEMBERS
            ,EXISTING [Calendar].[Calendar].[Month].MEMBERS
            )
        ,[Measures].[OBSERVATIONS] = 0
        )
    ) = 0
  ,[Measures].[AVERAGE]
  ,"^^"
 )

EDIT 3:

Found a limitation;

the measure only works if the date range defined for the cube is in a whole increment of the calendar hierarchy; i.e. a single month, a single quarter, or a single year. doing 2 months, 2 quarters, 2 years, or breaking across 2 quarters or years will return the False outcome from the IIF() expression.

I played around with a few different ways to set it up, but can't get it to work.

EDIT 4:

Re: calendar hierarchy

Looking underneath [calendar].[calendar] there are 4 options: Year, Quarter, Month, & Date Key.

looking at the members under Year, Quarter, & Month, you can drill down all the way to the individual day.

The member properties under those 3 lists just the next level up the hierarchy

On Date Key, the member properties are as follows: Month Name Month of Year Time Calcs (this doesn't do much to my knowledge) Week of Year Week

EDIT 5:

So this is what worked (finally). I must have messed something up at some point, and editing the original formula caused the secondary issue I was having. Here's what worked for me.

IIF
 (
  [Measures].[OBSERVATIONS]>=100 
  AND 
  COUNT
    (
     FILTER
        (
        EXISTS
            (
            [Calendar].[Calendar].[Month].Members
            ,EXISTING [Calendar].[Calendar].Members
            )
        ,[Measures].[OBSERVATIONS] = 0
        )
    ) > 0
  ,[Measures].[AVERAGE]
  ,"^^"
 )
1

1 Answers

1
votes

Using the EXISTING clause comes in handy at times when you want your calculation to recognize a certain selection(context). Following code is self explanatory. Let me know if it works.

WITH SET ZeroObservationMonths AS
FILTER
    (
    EXISTS
        (
        [Calendar].[Calendar].[Month].MEMBERS
        ,EXISTING [Calendar].[Calendar].[Date].MEMBERS
        )
     ,[Measures].[OBSERVATIONS] = 0
     )


MEMBER Measures.NewMeasure AS
IIF
 (
  [Measures].[OBSERVATIONS]>=100 AND COUNT(ZeroObservationMonths) > 0
  ,[Measures].[AVERAGE]
  ,"^^"
 )

SELECT [Project].[ProjectCode].MEMBERS ON 1,
Measures.[NewMeasure] ON 0
FROM [YourCube]
WHERE ({[Calendar].[Calendar].[Date].&D1: [Calendar].[Calendar].[Date].&D2})

EDIT: If you're planning on creating the measure inside excel, just have the below MDX code in the text box for "New calculated measure"

IIF
 (
  [Measures].[OBSERVATIONS]>=100 
  AND 
  COUNT
    (
     FILTER
        (
        EXISTS
            (
            [Calendar].[Calendar].[Month].MEMBERS
            ,EXISTING [Calendar].[Calendar].[Date].MEMBERS
            )
        ,[Measures].[OBSERVATIONS] = 0
        )
    ) > 0
  ,[Measures].[AVERAGE]
  ,"^^"
 )

EDIT 2: If the filtering can happen on any attribute, not just dates, replace EXISTING [Calendar].[Calendar].[Date].MEMBERS with EXISTING [Calendar].[Calendar].MEMBERS in the script above.