MDX 查询以查找 icCube 中的最后一个非空值

MDX Query to find the last ever non empty value in icCube

在 Chris Web 的 post 之后,我正在寻找一种快速查找客户上次购买的方法。

我使用如下 MDX 语句:

WITH FUNCTION previous_buys() AS tail( nonempty({NULL:[Time].[Time].currentmember.prevmember} ,[measures].[sales amt]),1)
MEMBER [last buy] as previous_buys().(0).key

select [measures].[last buy] on 0
,      [Customers].[Customers].[name].members on 1
from [Store Sales]
where [Time].[Time].[day].&[2015-12-20T00:00:00.000]

这符合预期,但需要很长时间。有没有一种简单的方法可以以某种方式加快此查询的速度。由于 icCube 与 Microsoft MDX 有所不同,我不能只复制 Chris Web 的解决方案。

有什么想法吗?

相对于 AdvWrks,使用 SSAS 相对较快。我合并了两个自定义结构(需要从 FUNCTION 进行更改,因为我认为这不是 MS 实现 mdx 的一部分):

WITH 
  MEMBER [Measures].[previous_buys] AS 
    Tail
    (
      NonEmpty
      (
        {NULL : [Date].[Calendar].CurrentMember.PrevMember}
       ,[Measures].[Internet Sales Amount]
      )
    ).Item(0).Item(0).Member_Key 
SELECT 
  NON EMPTY 
    [Measures].[previous_buys] ON 0
 ,NON EMPTY 
    [Product].[Product Categories].[Product] ON 1
FROM [Adventure Works]
WHERE 
  [Date].[Calendar].[Date].&[20071015];

结果如下:

这个解决方案的主要问题是可扩展性,因为我们正在评估 {NULL:[Time].[Time].currentmember.prevmember} 计数成员。

我认为使用带有 Head 函数的 Reverse 不会评估整个集合,但 Empty 函数的当前实现 'materializes' 集合。这意味着我们正在评估所有成员。还不是有效的解决方案。

另一个更优雅的解决方案是使用递归函数。这将大大减少评估的成员数量。

WITH 
  FUNCTION previous_buys(t_) AS IIF( (t_,[Measures].[Amount]) = NULL,  previous_buys(t_.prevMember), t_ )
  MEMBER [last buy] as previous_buys( [Time].[Calendar].current).name

SELECT 
  [measures].[last buy] on 0,
  [Customers].[Geography].[Region]  on 1
FROM [Sales]
WHERE [Time].[Calendar].[Year].[2006].[Q1 2006].[Jan 2006].[8 Jan 2006]

如果您有很多空日期,您可能会使算法复杂化到一个月级别以检查是否空。这将在一次迭代中评估整个月,而不是我们在当天版本中的 30/31。


最后一个也是最快的一个数量级依赖于icCube的聚合引擎。我们在这里想要的是 returns 最后一天的度量。

我们的想法是添加一个以日期作为输入值并以最大值作为聚合方法的度量。然后我们将使用 eval - 这很重要,因为我们正在缓存子多维数据集 - 在具有这个新度量的集合上。