Как фильтровать значения мер в MDX, имея элементы измерения на обеих осях - PullRequest
0 голосов
/ 10 января 2019

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

Мне нужно обеспечить базовую фильтрацию значений мер (равно, больше, меньше, чем и т. Д.), И в настоящее время я анализирую правильный способ генерации MDX.

Просматривая некоторую документацию (и другие темы на этом сайте), я обнаружил, что наиболее эффективным подходом будет использование функций FILTER или HAVING для фильтрации нежелательных значений.

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

Что я уже сделал?

Чтобы было проще объяснить, скажем, мы хотим получить годовые объемы продаж с помощью фильтрации по классам продуктов количество> 1,3 млн.

Попытка использовать функции HAVING или FILTER приводит к получению MDX

SELECT 
NON EMPTY {[YearList].[Year].[Year].MEMBERS * [Measures].[Qty]} 
    HAVING [Measures].[Qty] > 1.3e6 ON COLUMNS,
NON EMPTY {[Classes].[cClass].[cClass].MEMBERS} 
    HAVING [Measures].[Qty] > 1.3e6 ON ROWS
FROM [Model]

или

SELECT 
NON EMPTY FILTER({[YearList].[Year].[Year].MEMBERS * [Measures].[Qty]}, 
    [Measures].[Qty] > 1.3e6) ON COLUMNS,
NON EMPTY FILTER({[Classes].[cClass].[cClass].MEMBERS} , 
    [Measures].[Qty] > 1.3e6) ON ROWS
FROM [Model]

Но это, конечно, приводит к неожиданному результату для конечного пользователя, потому что фильтр происходит при агрегировании величин только по измерению на этой оси, которое больше 1,3M

Wrong Result

Единственный способ найти то, что мне нужно, - это определить пользовательский элемент с помощью оператора IIF

WITH
    MEMBER [Measures].[FilteredQty] AS 
    IIF ( [Measures].[Qty] > 1.3e6, Measures].[Qty], NULL)

SELECT 
    NON EMPTY {[YearList].[Year].[Year].MEMBERS * [Measures].[FilteredQty]} ON COLUMNS,
    NON EMPTY {[Classes].[cClass].[cClass].MEMBERS} ON ROWS
FROM [Model]

Результат, ожидаемый:

Expected Result

Это лучший подход, или я должен продолжать использовать функции FILTER и HAVING ? Есть ли еще лучший подход, который я все еще скучаю? Спасибо

1 Ответ

0 голосов
/ 10 января 2019

Это лучший подход. Вы должны рассмотреть, как MDX разрешает результат. В приведенном выше примере это совпадение, что ваши действительные данные в непрерывной области первых четырех столбцов первой строки. Давайте ослабим условие фильтрации и сделаем его> 365000. Теперь взгляните на последнюю строку результата, первые два столбца и последний столбец являются допустимыми ячейками, но третий и четвертый столбец не имеют права. Однако ваш запрос будет сообщать об этом как нулевой, и непустая функция не поможет. Причина в том, что непустому нужна вся строка, чтобы быть нулевым Теперь вопрос, почему фильтр не устраняет ячейку? Фильтр удалит строку или столбец, если критерий больше суммы на другой оси. Таким образом, если фильтр для столбцов, значение фильтра должно быть больше, чем сумма строк для этого столбца. Посмотрите на образец ниже, как только вы удалите комментарии, последний столбец будет удален.

select 
non empty
filter(
([Measures].[Internet Sales Amount]
,{[Date].[Calendar Year].&[2013],[Date].[Calendar Year].&[2014]}
,[Date].[Calendar Quarter of Year].[Calendar Quarter of Year]
),([Date].[Calendar Year].currentmember,[Date].[Calendar Quarter of Year].currentmember,[Product].[Subcategory].currentmember,[Measures].[Internet Sales Amount])>45694.70--+0.05
)
on columns 
,
non empty
[Product].[Subcategory].members
on rows
from
[Adventure Works]

enter image description here

Редактировать еще один добавленный образец.

with 
member [Measures].[Internet Sales AmountTest]
as 
iif(([Date].[Calendar Year].currentmember,[Date].[Calendar Quarter of Year].currentmember,[Product].[Subcategory].currentmember,[Measures].[Internet Sales Amount])>9000,
([Date].[Calendar Year].currentmember,[Date].[Calendar Quarter of Year].currentmember,[Product].[Subcategory].currentmember,[Measures].[Internet Sales Amount]),
null
)


select 
non empty
({[Measures].[Internet Sales Amount],[Measures].[Internet Sales AmountTest]}
,{[Date].[Calendar Year].&[2013]}
,[Date].[Calendar Quarter of Year].[Calendar Quarter of Year]
)
on columns 
,
non empty
[Product].[Subcategory].[Subcategory]
on rows
from
[Adventure Works]

enter image description here

...