Quantcast
Channel: SQL Server Analysis Services Forum
Viewing all articles
Browse latest Browse all 2472

Creating a generic calculation (as a stored procedure?)

$
0
0

What I need

There are many-to-many relationships between dimensions [D1][D2][D3] and measure [M].

I need to create a generic calculated measure that would have the following formula: [M] / Σ( [M] ), where Σ stands for the sum of all measure's facts that are associated with at least one member of a given dimension.

What I've tried

It is possible to define Σ( [M] ) as a calculated measure, using MDX:

CREATE HIDDEN [Total M] =
  AGGREGATE(
    DESCENDANTS(
      AXIS( 1 ).ITEM( 0 ).DIMENSION.LEVELS( 0 ).ITEM( 0 ),
      AXIS( 1 ).ITEM( 0 ).DIMENSION.LEVELS.COUNT
    ) - AXIS( 1 ).ITEM( 0 ).DIMENSION.LEVELS( 0 ).ITEM( 0 ),
    [Measures].[M]
  );

I have to aggregate over all members, except the [All] member. But this solution works. (If I don't exclude[All], the total value of [M] in the cube is returned, because I'm not slicing by this dimension. And also because the relationship is many-to-many.)

Using AXIS( 1 ) makes the measure generic, being able to work with any of the "many-to-many" dimensions. (Actually, I use AXIS( [DimInd] ), where [DimInd] is a measure I wrote that returns the index of the first axis that contains a dimension).

Now I can define my desired measure:

CREATE MEMBER CURRENTCUBE.[Measures].[Share of M] AS
  [Measures].[M] / [Measures].[Total M]

But the generic nature of it has downsides as well. For example, the following query fails because of infinite recursion:

SELECT [Measures].[Share of M] ON 0,
ORDER( [D1].MEMBERS, [Measures].[Share of M] ) ON 1
FROM [MyCube]

Which is actually logical — to get AXIS( 1 ).ITEM( 0 ) in [Total M], SSAS needs to first get a set of members on axis 1, but this set is impossible to obtain until the members are sorted by [Share of M]. It is a circular dependency.

This example shows that this generic measure can only be used in very simple queries. In real life, it is as good as useless.

What to do?

Maybe there is a way of implementing this using MDX, but I really don't see it. Please give me an advice in case you know of a solution.

Another direction I want to try is writing a stored procedure, which would perform all needed calculations in a generic way. But I'm stuck on that route as well.

Can I, in my stored procedure, somehow find out which dimension is currently being used (similarly toAXIS( 1 ))?




Viewing all articles
Browse latest Browse all 2472

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>