SSAS标准版-从事务粒度的事实表中获取最后一个值 背景

SSAS标准版-从事务粒度的事实表中获取最后一个值 背景,ssas,mdx,olap,cube,Ssas,Mdx,Olap,Cube,嗨!我试图在SSAS2008R2标准版中使用非加性度量,因为我知道在这个版本中,半加性/非加性度量不能立即使用 我正试图从一个事实表中计算一个最近的发票价格,这个事实表看起来像这样(很抱歉,如果这不是在这些帖子中创建表的正确方法!): 单价定义为最后一个子度量。发票编号和发票行用于生成退化维度。在Chris Webb的博客文章之后,我可以毫无问题地获取各个日期的最后一个单价 问题 但是,当一个项目在事实表中的同一天有两条记录时(如上表所示),当使用Date维度浏览多维数据集时,每条记录的单价仍然

嗨!我试图在SSAS2008R2标准版中使用非加性度量,因为我知道在这个版本中,半加性/非加性度量不能立即使用

我正试图从一个事实表中计算一个最近的发票价格,这个事实表看起来像这样(很抱歉,如果这不是在这些帖子中创建表的正确方法!):

单价定义为最后一个子度量。发票编号和发票行用于生成退化维度。在Chris Webb的博客文章之后,我可以毫无问题地获取各个日期的最后一个单价

问题 但是,当一个项目在事实表中的同一天有两条记录时(如上表所示),当使用Date维度浏览多维数据集时,每条记录的单价仍然会聚合。我的魔方没有在2016-09-01上显示$10,而是返回$10+$10=$20

解决? 描述类似于相同问题的内容,并通过向日期维度添加小时/秒/毫秒来解决该问题。有没有其他方法可以在不修改日期维度的情况下处理这种情况

我完全是MDX的新手,但我希望它能有所帮助。是否有MDX计算可以从具有[Invoice No]记录的当前日期成员检索单价,而不是在[ALL]级别执行聚合

我可以将事实表的粒度更改为sales by day,并在TSQL中处理所有的计算,这让我感觉舒服多了,但这与我从Ralph Kimball那里读到的关于维度建模的内容背道而驰,我试图将事实表保持在尽可能低的粒度

在ETL过程中,我还可以使用ROW_NUMBER()在底层SQL表中处理此问题,然后在SSAS中创建最小或最大度量值

最后,我可以通过除以扩展价格/数量来计算平均单价,但如果可能的话,检索一天内最后一张发票的实际价格会更好


谢谢大家!

如果您想获得最后一个价格:

Select 
Tail(
    NonEmpty(
        {
            [DateId].[DateId].[DateId].Members *
            [Invoice Line].[Invoice Line].[Invoice Line].Members *
            [Invoice No ].[Invoice No ].[Invoice No ].Members *
            [ProductId].[ProductId].[ProductId].Members *
            [Unit Price].[Unit Price].[Unit Price].Members
        },
        [Measures].[Invoice Count]  
    ),
    1
) on 1,
[Measures].[Invoice Count] on 0
From [YourCube]
如果每个客户都需要相同的,则可能需要使用Generate()函数:

Select 
Generate(
    [CustomerId].[CustomerId].[CustomerId].Members,
    Tail(
        NonEmpty(
            {
                [CustomerId].[CustomerId].CurrentMember *
                [DateId].[DateId].[DateId].Members *
                [Invoice Line].[Invoice Line].[Invoice Line].Members *
                [Invoice No ].[Invoice No ].[Invoice No ].Members *
                [ProductId].[ProductId].[ProductId].Members *
                [Unit Price].[Unit Price].[Unit Price].Members
            },
            [Measures].[Invoice Count]
        ),
        1
    )
) on 1,
[Measures].[Invoice Count] on 0
From [YourCube]
为了提高性能,我建议添加带有最大聚合的度量YYYYMMDDPP样式。其中YYYYMMDD是日期代码,PP是价格值。例如:

| Invoice No | Invoice Line | DateId   | ProductId | Unit Price | DatePrice  |
|------------|--------------|----------|-----------|------------|------------| 
| 1          | 1            | 20160901 | 2         | 10         | 2016090110 | 
| 4          | 2            | 20160901 | 2         | 10         | 2016090110 |
它将返回一个最大值。你的情况是2016090110。为了获得唯一的价格,您需要额外的计算方法:

With

Member [Measures].[Last Price] as
Right([Measures].[MaxDatePrice],2)

Select [Measures].[Last Price] on 0
From [BI Fake]
您可能需要扩大PP尺寸。这取决于你们的价格范围

编辑:由于您的静态价格大小为7,因此需要执行以下步骤:

创建YYYYMMDDPPPP格式的DatePrice字段:

 [PriceDate] =
      year([DateId]) * 10000000000 +
      month([DateId]) * 100000000 +
      day([DateId]) * 10000000
      + [Unit Price]
创建计算的度量值:

Cint(Right([Measures].[MaxDatePrice],7))

Cint将把0000010转换成10。

TAIL和NoneEmpty的组合让我走上了正确的轨道!我将一个新度量定义为
TAIL(非空([Invoice\u DD].[Invoice No].MEMBERS*[Measures].[Unit Price]))。项(0)
,然后,无论在同一日期发生了多少条记录,或者我在日期层次结构中的什么位置,它都会像我希望的那样拉取最后一个价格。救命啊!很高兴知道我能帮上忙。虽然这确实返回了正确的结果,但速度非常慢。我仍在努力寻找计算速度更快的方法。我没有:这些值可以从两位数到七位数不等。另外,这难道不只是帮助我在给定的一天获得最大的价值,而不一定是最后的价值吗?我想我需要做的是让发票成为一个“年-月-日”的孩子,但这似乎不是一个好方法。最后,我用扩展价格除以数量得到了一个平均单价,这是两个完全相加的度量。一定是我自己检查的。我将编辑我的答案以了解详细信息。
Cint(Right([Measures].[MaxDatePrice],7))