我正试图找出一种方法可以过滤掉我的多维数据集中的数据,以便我可以执行时间序列计算,例如仅使用该子集的移动平均值。
例如,假设我有一个包含以下列的事实表:
我还有一个时间维度,其复合键为 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天。
我在这里做错了什么,有没有更好的方法可以过滤我的时间维度以消除计算中不需要的行?
答案 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函数将两个明确定义的集合放在一起。