MDX 在多个维度上获取 TopCount 并添加 rest/remainder (icCube)

MDX Get a TopCount over multiple dimensions and add a rest/remainder (icCube)

我想在多个维度上创建一个 TopCount,并包括一个“rest”/“remainder”和一个小计

我在 icCube 的默认销售模式上使用以下 MDX:

with
   
   member [Product].[Product].[All Products].[rest] as "All Products - top 2"
   
   SET [top] AS    
   Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
          TopCount(  s1.CurrentMember * [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) +  s1.CurrentMember * {[Product].[Product].[All Products].[rest] , [Product].[Product].[All Products]} )
   
select
   
   [Measures].[Amount]  on 0
   [top]      on rows
   
   from sales

结果如下图

如何获取“rest”的值? 使用公式:“所有产品”-/- 前 2

经过一段时间的困惑,我找到了解决方案。

解决办法是结合icCube的MDX++函数,即SubCubeMinus in combination with the category member.

答案如下:

with
   
   SET [top 2]  as
   Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
          TopCount(  s1.CurrentMember * [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) )
   
   category calculated member  [Product].[Product].[All Products].[rest] as subcubeminus(([Customers].[Geography].[All Regions] , [Time].[Calendar].[2010], [Product].[Product].[All Products]) , [top 2])
  
   SET [top 2]  as
   Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
          TopCount(  s1.CurrentMember * [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) )
   
   SET [tuples_top2_rest_total] AS    
   Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
          TopCount(  s1.CurrentMember * [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) +  s1.CurrentMember * {[Product].[Product].[All Products].[rest] , [Product].[Product].[All Products]} )
   
select
   
   [Measures].[Amount]  on 0
   [tuples_top2_rest_total]   on rows
   
from sales

结果

说明

  1. 使用生成函数创建前 2 名;
  2. 创建计算类别成员“rest”(即其他)立方体中 2010 年 Total Region 和 Total Product 的所有数据减去 region 和 2010 的每个组合的前 2 个。

答案将取决于维度是否包含 many-to-many 关系。

如果没有many-to-many,可以使用SubCubeComplement函数:

MEMBER [Product].[Product].[All Products].[rest] as Eval(  SubCubeComplement( TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]) ) ,  [Product].[Product].defaultMember )

或者计算(全部减去TopCount集合的总和):

MEMBER [Product].[Product].[All Products].[rest] as  ([Product].[Product].defaultMember) - Sum( TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]), [Product].[Product].currentMember )

这里的风险是,如果你有 many-to-many 关系,上面的两个解决方案可能会减去不需要的行(因为它们可能包含应该在最终集合中的文章。)

因此,如果您有 many-to-many 关系,请使用具有以下语法的 Eval 函数:

MEMBER [Product].[Product].[All Products].[rest] as  Eval( [Product].[Product].[Article].Members -  TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]), [Product].[Product].defaultMember )

因此该语句将是(请注意对 [top] 集合定义的调整):

with
   
// v1 (no many-to-many) - behaves like a FILTERBY
   // MEMBER [Product].[Product].[All Products].[rest] as Eval(  SubCubeComplement( TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]) ) ,  [Product].[Product].defaultMember )
   
//v2 (no many-to-many)
   // MEMBER [Product].[Product].[All Products].[rest] as  ([Product].[Product].defaultMember) - Sum( TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]), [Product].[Product].currentMember )
   
//v3 (many-to-many)
   MEMBER [Product].[Product].[All Products].[rest] as  Eval( [Product].[Product].[Article].Members -  TopCount(   [Product].[Product].[Article].Members, 2, [Measures].[Amount]), [Product].[Product].defaultMember )
   
   SET [top] AS    
   Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
          s1.CurrentMember * TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) +  s1.CurrentMember * {[Product].[Product].[All Products].[rest] , [Product].[Product].[All Products]} )
   
select
   
   [Measures].[Amount]  on 0
   [top]      on rows
   
   from sales

如果没有 many-to-many 关系,版本 3 也可以使用。