SSAS标准版 - 从事务处理中的事实表中获取最新值

时间:2017-04-20 20:31:52

标签: ssas mdx olap cube

背景

嗨!我正在尝试在SSAS 2008R2标准版中使用非添加剂测量,因为他知道半/非添加剂测量在本版本中不能立即使用。

我正在尝试计算从事实表开具的最后一个价格看起来像这样(对不起,如果这不是在这些帖子中创建表格的正确方法!):

| Invoice No | Invoice Line | DateId   | ProductId | Unit Price |
|------------|--------------|----------|-----------|------------|
| 1          | 1            | 20160901 | 2         | 10         |
| 4          | 2            | 20160901 | 2         | 10         |   

单价定义为最后一个子度量。发票号码&发票行用于生成退化维度。在Chris Webb的博客文章Last Ever Non Empty – a new, fast MDX approach之后,我可以毫无问题地获取日期的最后一个单价。

问题

但是,当一个项目在同一天的事实表中有两个记录时 - 如上表所示 - 使用日期维度浏览多维数据集时,每个记录的单位价格仍然会聚合。而不是在2016-09-01上显示10美元,我的立方体返回10美元+ 10美元= 20美元。

解决方案?

This post描述了听起来像是同一个问题的内容,并通过在Date维度中添加Hours / Seconds / Milliseconds来解决它。有没有其他方法可以在不修改日期维度的情况下处理这种情况?

我是MDX的新手,但我希望它可以提供帮助。是否有MDX计算可以某种方式从具有[发票号]记录的当前日期成员中检索单价而不是在[全部]级别执行汇总?

我可以将我的事实表的粒度改为白天销售并处理TSQL中我觉得更舒服的所有计算,但这与我从Ralph Kimball读到的关于维度建模和尝试的内容相反。将事实表保持在尽可能低的粒度。

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

最后,我可以通过除以延长价格/数量来计算单价作为平均值,但如果可能的话,在一天中检索最后一张发票的实际价格会很棒

谢谢!

1 个答案:

答案 0 :(得分:0)

如果你想获得最后的价格:

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]

为了提高性能,我建议使用MAX聚合添加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,因此您需要执行以下步骤:

以YYYYMMDDPPPPPPP格式创建DatePrice字段:

 [PriceDate] =
      year([DateId]) * 10000000000 +
      month([DateId]) * 100000000 +
      day([DateId]) * 10000000
      + [Unit Price]

创建计算度量:

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

Cint会将0000010转换为10。