Shedal
@Shedal

[SSAS] Универсальная расчётная мера (возможно, используя хранимую процедуру)?

Чего нужно достичь

Есть измерения [D1], [D2], [D3] и мера [M].

Каждое измерение связано с [M] как многие-ко-многим.


Мне нужно создать универсальную меру с формулой [M] / S( [M] ), где S — сумма всех фактов меры, ассоциированных хотя бы с одним членов текущего измерения (текущего = использующегося в MDX-запросе).

Что я пробовал

S( [M] ) можно задать в качестве расчётной меры, используя 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]
  );


Приходится аггрегировать все члены, кроме [All], но такое решение работает. (Если же брать общее значение [M] по всему измерению, то значение получается неверным, потому что тип связи — многие-ко-многим.)


Ипользование AXIS( 1 ), — на самом деле, AXIS( [First Dimension Index] ), — позволяет этой расчётной мере быть универсальной и работать с любым из измерений [D1], [D2], [D3].


Теперь можно задать и меру по формуле [M] / S( [M] ):

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


Однако, такая универсальность имеет и недостатки. Например, следующий запрос вернёт ошибку «бесконечная рекурсия»:

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


Это, впрочем, достаточно логично, ведь, чтобы получить AXIS( 1 ).ITEM( 0 ), который мы используем в [Total M], SSAS необходимо сначала получить множество всех членов на оси 1. Но чтобы получить это множество, сначала нужно отсортировать члены [D1], используя ту же самую меру. Возникает циклическая зависимость.


Получается, что такую универсальную меру можно использовать только в самых простых запросах. А в реальных условиях она практически бесполезна.

Что делать?

Может быть, и есть способ решить задачу при помощи MDX, но у меня это не получается. Так что, если у вас есть идеи, то пожалуйста подскажите, в какую сторону двигаться.


Другое направление, которое я хочу попробовать, — написать хранимую процедуру на C#, которая бы производила все нужные вычисления. Но и здесь я застрял — я не знаю, как получить текущее измерение (по аналогии с AXIS( 1 ).ITEM( 0 ).DIMENSION).
  • Вопрос задан
  • 3434 просмотра
Решения вопроса 1
Shedal
@Shedal Автор вопроса
Решение помогли найти на форумах MSDN: social.msdn.microsoft.com/Forums/en-US/sqlanalysisservices/thread/04019705-5b65-48f8-b403-a6d015c9dec5
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы