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

Art*_*hur 5 performance mdx iccube

在Chris Web 的帖子之后,我正在寻找一种快速查找客户最后购买的方法.

我使用如下的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]
Run Code Online (Sandbox Code Playgroud)

这给出了预期,但需要很长时间.是否有一种简单的方法来加速这种查询.由于icCube与Microsoft MDX有所不同,我不能只复制Chris Web的解决方案.

有任何想法吗?

ic3*_*ic3 2

此解决方案面临的主要问题是当我们评估 {NULL:[Time].[Time].currentmember.prevmember} 计数成员时的可扩展性。

我认为使用带有 Head 函数的 Reverse 不会评估整个集合,但 Empty 函数的当前实现“具体化”了该集合。这意味着我们正在评估所有成员。还没有一个有效的解决方案。

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

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]
Run Code Online (Sandbox Code Playgroud)

如果您有很多空日期,则可能会使算法变得复杂一些,降低到一个月的级别来检查空​​日期。这将在一次迭代中评估整个月,而不是我们在日版本中的 30/31。


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

这个想法是添加一个以日期作为输入值、以最大值作为聚合方法的度量。然后我们将使用 eval - 很重要,因为我们缓存了子立方体 - 在带有这个新度量的集合上。