1

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

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

  • DayId(键)
  • 小时 ID(键)
  • 价值

我还有一个 Time 维度,其中包含DayIdHourId的复合键。此维度在 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 个元组的值,而是执行前一个的平均值9 天,12 小时 ID。

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

4

1 回答 1

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 构造分解为一个单独的块,因为这似乎是一项艰苦的工作。做对了,平均很容易。

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

于 2012-10-21T12:54:22.063 回答