MicroStrategy - 带连接的动态属性

时间:2014-02-28 17:50:16

标签: microstrategy

在我们的MicroStrategy 9.3环境中,我们有一个具有多个日期维度的星型模式。对于此示例,假设我们有一个order_fact表有两个日期,order_date和ship_date以及一个invoice_fact表,其中包含两个日期invoice_date和actual_ship_date。我们的日期维度包含“日历”相关数据。根据MicroStrategy高级数据仓库指南,我们使用别名设置每个日期,这是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:将“三个日期”更改为“两个日期”。

2 个答案:

答案 0 :(得分: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将使用它从父属性转到事实表。

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

答案 1 :(得分:0)

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

它就像魅力一样!