我对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)
)
答案 0 :(得分:1)
我会从scorestable创建一个维度表:如果它还没有,则为它添加一个主键列,并在SQL中计算 - 根据事实表中的偏差 - 您需要的scorestable中的条目参考。然后得分的得分得到这个维度的属性。
此SQL逻辑可以直接在填充表的过程中完成,也可以基于您随后在数据源视图中引用的表或基于计算查询/计算列的数据源视图中的视图完成。
如果你不想在SQL端拥有这部分逻辑,那就有点棘手:首先,由于MDX只能访问多维数据集对象而没有表,我们必须使该表可用于多维数据集: / p>
from_perc
作为唯一属性,从中创建维度。您可以为维度保留名称“得分表”,并为此属性保留BIDS生成的“From Perc”,或更改它们,在我的MDX下面我将假设自动名称。Score
从同一个表创建一个度量值组,该表只有一个度量值:让我们称之为“_Score”。您可以将聚合保留为“Sum”,这实际上从未在聚合级别使用。现在我们有了对象,我们可以使用以下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].CurrentMember
是All
成员,因为此属性层次结构是不可见的,因此我们可以假设它不用于列,行或切片器。然后,我们检查偏差是否大于From Perc
属性层次结构的最后一个成员的键的得分。由于我们没有声明属性的任何特定顺序,因此它由Analysis Services按键排序,因此最后一个成员是最大的成员。如果该值大于键值,我们就完成了,并返回该值的分数值。
(Tail([set]).Item(0).Item(0)
构造获取一维集的最后一个成员。)
否则,我们开始递归,再次调用成员定义,但这次使用最后一个成员作为CurrentMember
。然后我们到达主ELSE
的{{1}}分支,并在此处进行类似的检查:如果偏差大于当前成员的密钥,我们完成递归并返回值。否则,我们再次递归。如果不再存在CASE
,Analysis Services会自动停止递归。
请注意 - 如果表中的数据通过将其设置为ROLAP而更改,则可以避免重新处理度量值组,但维度没有这样的事情:您始终必须重新处理维度如果PrevMember
列中的任何内容发生更改,或者添加或删除了记录。但是,由于该表可能很小,因此应该很快。您甚至可以将度量值组设置为MOLAP的默认设置,并将其包含在重新处理中,而不会显着延长处理时间。