Friday, February 1, 2008

Scope

Scope is a tricky term to understand and in my opinion is not properly done - at least not in DMR.

IMO scope is the lowest level of granularity in a hierarchy for a measure's value.
If we want a value for higher levels then we roll up.

Cool. What about lower levels?
Cognos does not give any value for lower levels.

I think it's wrong. They mix access with granularity. You do not have access to measures that are not in scope. What the heck? You are taking away my access? For what?
I think the value should just be repeated, propagated down to lower levels.

Let me explain by an example.

Let's say we have an Annual Sales Target that is defined for each year. Our Time Dimension has the usual levels: Year, Month, Date
It wouldn't make sense to associate a value of Sales Target with the Date or Month level.
  • every day or month would have the same value
  • it is an annual target, we need to compare it with a year's worth of sales anyways
  • how would we roll it up for a year?
so everything tells us that it should be set in scope for the Year level only.
Right.
Now what if I ask the question: What was the annual sales target on Jan 23, 2008?
Cognos won't supply a value.
Is this question meaningful? We need to roll-up the sales for an entire year before we can do anything meaningful, don't we? So we don't really need a value at the day level... do we?

How about this: for each day I want to calculate the rolling-total of sales for 365 days back in time; and then compare that with the annual sales target. So as the year progresses I'd have some idea if I'm on track. Now that would make sense!

Unfortunately Cognos doesn't work like this.

Moving the Annual Sales target to the lower levels in scope is a bad idea - remember our reasons for putting it at the year level?

Tip:
When you need a value at a lower level than its scope you can use a tuple(), parent() and currentMember() to get the value
e.g. this expression would work at the day level:
tuple([Annual Sales Target], parent(parent(currentMember([Time Dimension]))))

I like Python's philosophy: discourage bad behavior but do not prevent it.
Why are they preventing me from accessing the value from a higher level? Let me decide if it makes sense to use it!

No comments:

Post a Comment