1

在我们的 MicroStrategy 9.3 环境中,我们有一个具有多个日期维度的星型模式。对于此示例,假设我们有一个 order_fact 表有两个日期,order_date 和 ship_date 以及一个 invoice_fact 表有两个日期 invoice_date 和 actual_ship_date。我们有一个包含“日历”相关数据的日期维度。根据 MicroStrategy Advanced Data Warehousing 指南,我们为每个日期设置了别名,这是 MicroStrategy 推荐的处理角色扮演维度的方法。

现在解决问题。别名日期允许用户创建特定于别名日期的报告。但是,由于日期已被别名化,MicroStrategy 不会合并“日期”,因为它们看起来是不同的。举个例子,我不能轻易地放置一个按 order_date 和 invoice_date 显示订单数量和发票数量的报告,因为它会导致交叉连接。

我们一直在内部讨论的解决方案是创建一个名为 order_fact_date 和 invoice_fact_date 的新属性。这些日期将在运行时通过以下伪代码确定:

case when <user picked date> = 'order date' 
    then order_date
    else ship_date end as order_fact_date

case when <user picked date> = 'invoice date'
    then invoice_date
    else actual_ship_date as invoice_fact_date

我们当时的想法是,我们可以将“一般”日期维度映射到两个日期,这将使 MicroStrategy 能够在连接中利用同一个表,从而消除交叉连接问题。

清如泥?

编辑1:将“三个日期”更改为“两个日期”。

4

2 回答 2

0

如果我正确理解了您的问题,您已经创建了多个日期属性(具有不同的逻辑含义),并且它们映射到日历表的不同别名上。

除非用户在他们的报告中使用不同的单一事实表,否则没有问题,但是当他们使用来自销售和发票的指标/事实时,您会获得成倍的结果,因为“订单日期”和“发票日期”是不同的属性。

您的 SQL 类似于:

...
FROM order_fact a11
INNER JOIN invoice_fact a12
INNER JOIN lu_calendar a13
        ON a11.order_date = a13.date_id
INNER JOIN lu_calendar a14
        ON a12.invoice_date = a14.date_id
...

像往常一样,有可能的解决方案,并不是所有的都非常简单。

选项 1 - 单一日期属性

您在问题中提到了这种可能性,而不是使用“订单日期”和“发票日期”,只需使用单个“日期”属性并教用户使用它。如果这使他们的生活更轻松,您可以将其称为“报告日期”或“操作日期”。

你应该得到的 SQL 是这样的:

...
FROM order_fact a11
INNER JOIN invoice_fact a12
        ON a11.order_date = a12.invoice_date
INNER JOIN lu_calendar a13               -- Only one join
        ON a11.order_date = a13.date_id  -- because the date is the same
...

选项 2 - 我们需要保留两个日期属性!

在日历表的同一别名上映射“订单日期”和“发票日期”。这通常会在 MicroStrategy 中引起问题,因为两个属性将在同一个查找表中连接在一起 [见下文],但在您的情况下,这正是您正在寻找的。

使用此解决方案,您应该获得如下 SQL:

...
FROM order_fact a11
INNER JOIN invoice_fact a12           -- Hey! this is again a cross join!
INNER JOIN lu_calendar a13
        ON a11.order_date = a13.date_id     -- Relax man, we got you covered.
        AND a12.invoice_date = a13.date_id  -- Yes, we do it!
...

这很好,但只有当您有来自日历表的描述表单时才有效(日期并非总是如此,因为 ID 通常也是您在报告中显示的实际值)。如果您没有加入日历查找,您的 SQL 将再次以重复的结果结束:

...
FROM order_fact a11           -- Notice no join column between the two facts
INNER JOIN invoice_fact a12   -- and no other conditions will help to join them
...

出于这个原因,如果你想保持这两个属性分开,除了将它们映射到同一个查找上,你还应该:

  • 创建一个隐藏属性(我们称之为“Date_on_fact”)将其映射到事实表和日历表,并使其成为“订单日期”和“发票日期”的子项。
  • 从事实表中取消映射“订单日期”和“发票日期”。

这里的想法是强制 MicroStrategy 始终使用 SQL 代码,始终使用日历查找表:

...
FROM order_fact a11
INNER JOIN invoice_fact a12           -- This is like the previous one
INNER JOIN lu_calendar a13            -- But I'm back to help you
        ON a11.order_date = a13.date_id      
        AND a12.invoice_date = a13.date_id  
...

“Date_on_fact”属性实际上可以隐藏,用户无需将其放入报表中,但 MicroStrategy 将使用它从父属性转到事实表。

希望这可以帮助您摆脱困境。

于 2014-03-01T20:59:10.717 回答
0

我们遇到了同样的问题。我们必须为此创建一个通用时间层次结构,并将 2 个不同的发票和订单时间层次结构连接到通用时间层次结构。

它就像魅力一样!

于 2014-04-09T16:03:54.223 回答