Автор: Darren Gosbell
Дата публикации оригинала: 2008-07-26
Источник: Блог Darren Gosbell

Время от времени на SSAS MSDN forum поднимается вопрос о произведении универсальных расчетов «коэффициента отношения к текущему родителю». К сожалению, возникает ряд проблем с реализацией замысла предоставить пользователям обобщённую меру «коэффициента отношения к текущему родителю».

Первой проблемой является то, что концепция «родителя» по определению требует иерархии, а SSAS 2005 поддерживает множественные иерархии.

Рассмотрим данный запрос:

SELECT
Non Empty [Product].[Product].[Product].Members on Rows,
{Measures.[Sales Ratio]} ON Columns
FROM [Adventure Works]


Я использую атрибут [Product], который относится к двум определяемым пользователем иерархиям.

рис.1. Атрибут [Product] рис.2. Атрибут [Product]
Итак, что хочет увидеть пользователь? В контексте базы данных Adventure Works DW он, вероятно, ожидает увидеть Процент продаж продукта для Уровня резервных запасов или Подкатегории. Однако каждый продукт также является одноуровневой иерархией, которая подходит для возврата коэффициента каждого продукта к [Product].[Product].[All Products].

Но на этом веселье не заканчивается. Рассмотрим следующий запрос:


SELECT
[Date].[Calendar].[Month].Members on Rows,
{Measures.[Sales Ratio]} ON Columns
FROM [Adventure Works]
WHERE [Product].[SubCategory].[Mountain Bikes];


Как вы думаете, какого «родителя» хочет увидеть пользователь? Мы знаем, какую иерархию дат использовать, поскольку я задал иерархию [Calendar], но мы также режем по подкатегории [Mountain Bike], предоставляя другую правильную интерпретацию коэффициенту, основывающему на категории Bikes.

Вы, вероятно, можете предположить, что это может становиться все более и более сложным. Относительно простой запрос, как, например, следующий, имеет измерение по каждой оси и член, по которому выполняется разрезание, и, таким образом, теперь у нас появляются 3 возможных «родителя», из которых мы можем выбирать…


SELECT
[Date].[Calendar].[Month].Members on Rows,
[Promotion].[Promotion Category].[Promotion Category] ON Columns
FROM [Adventure Works]
WHERE (
[Measures].[Sales Ratio]
,[Product].[SubCategory].[SubCategory].[Mountain Bikes]
);


Проблема состоит в том, что в рамках многомерного пространства куба присутствует много родителей, и вы должны определить для MDX о каком именно родителе вы говорите. Даже в относительно простом запросе у вас может быть много измерений на одной оси, а, следовательно, и много потенциальных родителей.

С технической точки зрения, возможно «вроде бы» приблизиться, осуществляя что-то вроде указанного ниже, используя функцию Axis():

CREATE
MEMBER CURRENTCUBE.[MEASURES].[Sales Ratio] AS
IIF
(
(
[Measures].[Sales Amount]
,Axis(1).Item(0).Item(
Axis(1).Item(0).Count - 1).Hierarchy.CurrentMember.Parent
)
= 0
,null
,
[Measures].[Sales Amount]
/
(
[Measures].[Sales Amount]
,Axis(1).Item(0).Item(
Axis(1).Item(0).Count - 1).Hierarchy.CurrentMember.Parent
)

)
,FORMAT_STRING = "Percent"


Что даёт нам нечто похожее на вычисление «Процента строки родителя» и это, вероятно, лучшее, из того, что вы можете сделать, но, если вы выполните декартово произведение нескольких иерархий на оси строк, то снова столкнетесь с трудностями.

Вся идея «текущего родителя» в действительности намного более сложная, чем кажется на первый взгляд. В общем, необходимо избегать появления всего, что требует расчёта для определения текущего контекста запроса.

Учитывая все вышеизложенное, желательно производить специальные расчеты коэффициента или передать решение данной задачи на клиента. Некоторые клиентские инструменты позволяют пользователю определить расчёты или, если вы используете Excel, вы можете создать данные коэффициенты на одной стороне сводной таблицы.


Для удобства отслеживания новых публикаций рекомендуем подписаться на рассылку или на канал RSS.

Читайте также: