MDX计算成员通过维度属性过滤

15

我想创建一个计算成员并按维度进行过滤。以下是一份工作示例:

(
    [Policy].[Policy Status].&[Void], 
    [Policy].[Tran Type].&[Renewal], 
    [Measures].[FK Policy Distinct Count]
)

但是如果我想这样过滤它

(
    [Policy].[Policy Status].&[Void], 
    [Policy].[Policy Status].&[Policy],  
    [Measures].[FK Policy Distinct Count]
)

那么它不起作用。它说在元组中同一层次结构显示了多次。

另一件事是如何排除行? 这是一个想法...

(
    ![Policy].[Policy Status].&[Void], 
    ![Policy].[Policy Status].&[Policy],  
    [Measures].[FK Policy Distinct Count]
)
2个回答

55

首先,了解MDX语法及其与元组、成员和集合概念的关系非常重要。

元组

使用括号表示一个元组:

(
  [Policy].[Policy Status].&[Void], 
  [Policy].[Tran Type].&[Renewal], 
  [Measures].[FK Policy Distinct Count]
)

元组只能包含同一层级中的单个成员。

集合

要从同一层次结构中检索多个成员的结果,必须查询一个集合。MDX集合用大括号表示:

{
  [Policy].[Policy Status].&[Void], 
  [Policy].[Policy Status].&[Policy]
}

一个集合,按定义,

是一个有序的零个、一个或多个元组的集合。

因此,如果您希望针对这些成员查询[FK Policy Distinct Count]度量值,则集合的每个元组都必须包括该度量值:

{
  ( [Policy].[Policy Status].&[Void],   [Measures].[FK Policy Distinct Count] ), 
  ( [Policy].[Policy Status].&[Policy], [Measures].[FK Policy Distinct Count] )
}

为了简化这个表达式,可以将两个不同维度的集合crossjoin起来:
{
  [Policy].[Policy Status].&[Void],
  [Policy].[Policy Status].&[Policy], 
  [Policy].[Policy Status].&[Something], 
  [Policy].[Policy Status].&[Something else], 
  [Policy].[Policy Status].&[Yet another member]
}
*
{
  [Measures].[FK Policy Distinct Count]
}

排除行

既然我们可以定义集合,现在是时候从中删除一些成员了。在您的示例中,听起来您想从一个级别开始(对于MDX引擎来说,它只是立方体中预定义的包含该层次结构每个成员的集合),并排除某些成员。MDX有许多操作集合的函数,我们将使用EXCEPT

EXCEPT函数需要两个参数,第一个是要从中删除的集合,第二个是应从第一个中删除的集合。它返回一个集合。

在这个示例中,我假设[Policy].[Policy Status]是一个属性层次结构,并且其唯一名称为[Policy].[Policy Status].[Policy Status]

EXCEPT(
  [Policy].[Policy Status].[Policy Status],
  {
    [Policy].[Policy Status].&[Void],
    [Policy].[Policy Status].&[Policy]
  }
)

这将返回来自[Policy].[Policy Status].[Policy Status]层的每个成员,除了[Policy].[Policy Status].&[Void][Policy].[Policy Status].&[Policy]
为了获得有用的结果,我们可以通过度量交叉连接结果:
EXCEPT(
  [Policy].[Policy Status].[Policy Status],
  {
    [Policy].[Policy Status].&[Void],
    [Policy].[Policy Status].&[Policy]
  }
)
*
{
  [Measures].[FK Policy Distinct Count]
}

使用集合作为单个成员

集合很好用,但有时我们只想将它们视为单个成员,例如您的计算成员需求。要做到这一点,我们需要使用聚合函数。聚合函数接受一个集合并返回代表整个集合的成员。

有许多这样的函数,使用正确的函数取决于立方体中存储的数据:其中一些是MINMAXCOUNTSUM(请参见MDX函数参考中的“数值函数”以获取更完整的列表)。在本示例中,我将假设您的维度使用SUM进行聚合:

SUM(
  EXCEPT(
    [Policy].[Policy Status].[Policy Status],
    {
      [Policy].[Policy Status].&[Void],
      [Policy].[Policy Status].&[Policy]
    }
  ),
  [Measures].[FK Policy Distinct Count]
)

在这里,我已经将作为第二个参数聚合的度量传递给了SUM函数。


MDX是一种复杂的语言,支持许多常见和不常见的集合操作。如果您还没有这样做,我建议花时间阅读在线文档或获取一本好的MDX书籍。有很多需要了解 :)
<3

1
非常感谢您提供如此详细的解释。我已经尝试在计算成员(表单视图)字段中使用这些查询,但是它们都无法正常工作。它会抛出以下错误:“该函数期望参数为字符串或数字表达式。使用了元组集表达式”。 - ilija veselica
为了在单个成员中使用集合中收集的结果,需要使用聚合函数将集合转换。其中最容易使用的是AGGREGATE,因为它会自动选择正确的聚合类型(求和、最小值、最大值等)来处理集合。将计算成员定义为AGGREGATE(SetExpression)将允许您将结果用作单个成员。我会将此添加到答案中。 <3 - Tullo_x86
1
我已经尝试了AGGREGATE函数,但仍然返回错误信息:“在度量维度中无法对计算成员使用聚合函数”。我直接复制/粘贴了你在答案中提供的示例,但它并没有起作用。 - ilija veselica
好的。为了让AGGREGATE起作用,立方体必须已经定义了聚合函数--因此,它只能在最简单的查询中起作用。 - Tullo_x86

2
尝试使用以下语法:

SUM({[Policy].[Policy Status].&[Void], [Policy].[Policy Status].&[Policy]}, [Measures].[FK Policy Distinct Count])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接