在MDX中对OLAP数据的子集执行计算

时间:2012-10-19 22:00:17

标签: sql-server ssas mdx olap

我正试图找出一种方法可以过滤掉我的多维数据集中的数据,以便我可以执行时间序列计算,例如仅使用该子集的移动平均值。

例如,假设我有一个包含以下列的事实表:

  • DayId(Key)
  • HourId(Key)

我还有一个时间维度,其复合键为 DayId HourId 。此维度在100天的范围内每小时都有一个键,因此键从(1,1)到(100,24)。

在事实表中,每个时间点都有一个值,因此它看起来像

DayId HourId Value
1     1       50
1     2       60
1     3       75.2
...   ...     ...
100   23      87
100   24      89

现在,假设我想计算从一开始到一天中间某个任意点的每日移动平均线。基本上,我想用每天的最后一点来计算平均值,除了最后一点,这将在一天的中间使用不同的时间点。如果我要从第1天到第10天做一个移动平均线,在第10天中午结束(HourId 12),我用于计算的数据将如下所示:

DayId HourId Value
1     24     80
2     24     90
3     24     39
4     24     60
...   ...    ...
9     24     10 
10    12     30

在SQL中,我可以非常轻松地检索这样的集合:

SELECT 
    *
FROM
    [FactTable]
WHERE
    ((DayId BETWEEN 1 AND 9) AND (HourId = 24))
    OR ((DayId = 10) AND (HourId = 12))

我是OLAP和MDX的新手,所以我一直在努力用正确的方法来做到这一点。到目前为止,我能做的最好的事情是在我的FROM子句中执行子选择,并基本上构造一个仅包含我想要的行的元组:

WITH
    MEMBER [SMA 10 Value] AS
    AVG (
        ([Time].[DayId].Lag(9):[Time].[DayId], [Time].[HourId])
        , [Value]
    )
SELECT
    {
      [Value]
      , [SMA 10 Value]
    } ON COLUMNS
    , ([Time].[DayId], [Time].[HourId]) ON ROWS
FROM
(
    SELECT
        [Measures] ON COLUMNS
        , {
            ([Time].[DayId].[1]:[Time].[DayId].[9], [Time].[HourId].[24])
            , ([Time].[DayId].[10], [Time].[HourId].[12])
    } ON ROWS
    FROM
        [Cube]
)

然而,它似乎不适合我的计算。移动平均线在前9天似乎是正确的,因为它们的元组都具有相同的小时ID,但是当我到达最后一天时,它不是使用前9个元组中的值,而是执行前一个的平均值。带12小时身份证的9天。

我在这里做错了什么,有没有更好的方法可以过滤我的时间维度以消除计算中不需要的行?

1 个答案:

答案 0 :(得分:2)

我对MDX有点新意,所以请把它当作值得的东西,但这是我的解决方案。

With
SET [AvgOver] as
  UNION(
    ({[Time].[DayID].CurrentMember.Lag(9):[Time].[DayID].CurrentMember.Lag(1)},
        [Time].[HourID].24)
    ([Time].[DayID].CurrentMember, [Time].[HourID].CurrentMember)
  )
MEMBER [SMA 10 Value] as
  Avg(AvgOver, [Value])
Select
  ([Value], [SMA 10 Value]) on Columns,
  ([Time].[DayID].[10], [Time].[HourID].[12])
From [Cube]

我将SET构造分解为一个单独的块,因为这似乎是一项艰苦的工作。做到这一点,Avg很容易。

您说您想要使用当天选定的值和前9天的最终值进行平均值。那对我来说建议使用UNION函数将两个明确定义的集合放在一起。