SSAS评分范围表

时间:2014-02-12 21:18:51

标签: sql ssas mdx olap

我对SSAS多维数据集进行了以下MDX查询

select
non empty { [Measures].[Deviation Percent] * [Date].[Hierarchy].[Month].Members } on columns,
non empty { [Veh].[Registration].[All] } on rows
from
(select { [Date].[Hierarchy].[Month].&[9]&[2013] : [Date].[Hierarchy].[Month].&[1]&[2014] }   on columns from [DB])

如您所见,[Veh],[Date]是尺寸

我在数据源中有另一个表(ScoresTable),不包含在多维数据集中的任何位置,我用它来根据偏差百分比度量来分配分数。该表有两列,分数和From_Perc,行如下:

得分----- From_Perc

0 ----- -5

1 ------ 0

2 ------- 3

......等等

所以当偏差为-5到0时,得分为1,0到3,得分为2,当< -5得分为0时。 我需要在列上显示此分数而不是目标偏差,但我似乎无法弄清楚如何执行此操作。有什么建议吗?

注意:得分表可能会随时间变化,因此限制不能被认为是稳定的(即我不能使用带有硬编码值的Case和Iif语句来进行计算)。此外,计算偏差成员。

更新:感谢FrankPI的建议,问题的答案是创建一个像这样的计算成员:

(
    [Measures].[Score],
    tail(
         filter(
                [Fuel Scores Percentage].[From Perc].[From Perc],
                ([Measures].[Target Deviation] * 100)>[Fuel Scores Percentage].[From Perc].CurrentMember.Member_Value
               )
        ).item(0).item(0)
)

1 个答案:

答案 0 :(得分:1)

我会从scorestable创建一个维度表:如果它还没有,则为它添加一个主键列,并在SQL中计算 - 根据事实表中的偏差 - 您需要的scorestable中的条目参考。然后得分的得分得到这个维度的属性。

此SQL逻辑可以直接在填充表的过程中完成,也可以基于您随后在数据源视图中引用的表或基于计算查询/计算列的数据源视图中的视图完成。

如果你不想在SQL端拥有这部分逻辑,那就有点棘手:首先,由于MDX只能访问多维数据集对象而没有表,我们必须使该表可用于多维数据集: / p>

  • 将表格添加到数据源视图。
  • 使用from_perc作为唯一属性,从中创建维度。您可以为维度保留名称“得分表”,并为此属性保留BIDS生成的“From Perc”,或更改它们,在我的MDX下面我将假设自动名称。
  • 根据列Score从同一个表创建一个度量值组,该表只有一个度量值:让我们称之为“_Score”。您可以将聚合保留为“Sum”,这实际上从未在聚合级别使用。
  • 将维度添加到多维数据集维度,并检查它是否是与您在“维度用量”标签上添加的度量值组相关的唯一维度。
  • 将此度量值组的唯一分区的存储模式设置为“ROLAP”。

现在我们有了对象,我们可以使用以下MDX来计算Score度量:

with member [Measures].[Score] as
     CASE
       WHEN [Scores Table].[From Perc].CurrentMember IS [Scores Table].[From Perc].[All] THEN
         CASE
           WHEN [Measures].[Deviation Percent] > Tail([Scores Table].[From Perc].[From Perc]).Item(0).Item(0).Properties('Key0', typed) THEN
               -- found it: it is the last entry from ScoresTable:
               (
                [Measures].[_Score],
                Tail([Scores Table].[From Perc].[From Perc]).Item(0).Item(0)
               )
           ELSE
               -- start recursing the table with the last but one member:
               (
                [Measures].[Score],
                Tail([Scores Table].[From Perc].[From Perc]).Item(0).Item(0).PrevMember
               )
         END
       ELSE
         CASE
           WHEN [Measures].[Deviation Percent] > [Scores Table].[From Perc].CurrentMember.Properties('Key0', typed) THEN
               -- found the correct table entry, end of recursion, return it:
               (
                [Measures].[_Score],
                [Scores Table].[From Perc].CurrentMember
                )
           ELSE 
               -- not found, recurse to the previous table entry:
               (
                [Measures].[Score],
                [Scores Table].[From Perc].CurrentMember.PrevMember
               ) 
         END
     END

select ...

您也可以将其用作具有相同表达式的立方体计算度量。检查完成后,我建议将属性和度量都隐藏起来。

它是如何运作的?

MDX中的主循环结构是递归,也用于度量的定义。在起始点,[Scores Table].[From Perc].CurrentMemberAll成员,因为此属性层次结构是不可见的,因此我们可以假设它不用于列,行或切片器。然后,我们检查偏差是否大于From Perc属性层次结构的最后一个成员的键的得分。由于我们没有声明属性的任何特定顺序,因此它由Analysis Services按键排序,因此最后一个成员是最大的成员。如果该值大于键值,我们就完成了,并返回该值的分数值。 (Tail([set]).Item(0).Item(0)构造获取一维集的最后一个成员。)

否则,我们开始递归,再次调用成员定义,但这次使用最后一个成员作为CurrentMember。然后我们到达主ELSE的{​​{1}}分支,并在此处进行类似的检查:如果偏差大于当前成员的密钥,我们完成递归并返回值。否则,我们再次递归。如果不再存在CASE,Analysis Services会自动停止递归。

请注意 - 如果表中的数据通过将其设置为ROLAP而更改,则可以避免重新处理度量值组,但维度没有这样的事情:您始终必须重新处理维度如果PrevMember列中的任何内容发生更改,或者添加或删除了记录。但是,由于该表可能很小,因此应该很快。您甚至可以将度量值组设置为MOLAP的默认设置,并将其包含在重新处理中,而不会显着延长处理时间。