如何在两个轴上都有维成员的同时按MDX中的度量值进行过滤

时间:2019-01-10 12:01:29

标签: filter ssas mdx mdx-query

我正在开发一个使用表格数据库显示一些业务数据的应用程序。

我需要提供一些基本的过滤度量值(等于,大于,小于等),并且我目前正在分析生成MDX的正确方法。

通过查看一些文档(以及该站点上的其他线程),我发现最有效的方法是使用 FILTER HAVING 函数来过滤掉不需要的值

不幸的是,所有示例通常都在一个轴上包含度量,而在另一轴上包含维度成员,但是我可能在两个轴上都包含维度成员,并且找不到使用此类函数进行过滤的合适解决方案测量值。

到目前为止我做了什么?

为了便于解释,假设我们要通过产品类别过滤来获取年度销售量数量> 130万

尝试使用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 :(得分:0)

这是最好的方法。您需要考虑MDX如何解析结果。在上面的示例中,您的有效数据在第一行的前四列的连续区域中是一个巧合。让我们放宽过滤子句,使其大于365000。现在看一下结果的最后一行,前两列和最后一列是合格单元格,但第三列和第四列不合格。但是,您的查询会将其报告为null,并且非空函数将无济于事。原因是非空需要整行为空 现在为什么过滤器不能消除细胞的问题?当条件大于另一轴的总和时,过滤器将消除行或列。因此,如果过滤器位于列上,则过滤器值必须大于该列的行总和。删除注释后,请看下面的示例,最后一列将被删除。

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