2014-02-28 49 views
1

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

+1

哟写的invoice_fact包含三个日期,但你只提及invice_date和actual_ship_date,你能澄清? – mucio

+0

@mucio我更新了这个问题。谢谢! – Nick

+0

检查我的答案,我认为你的意思是两个 – mucio

回答

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将使用它从父属性转到事实表。

希望这可以帮助你摆脱泥泞。

+0

是否有可能在运行时解决“date_on_fact”?正如我在*上面解释的,不是很成功,我希望MicroStrategy能够根据订单事实加入订单日期或发货日期。发票表同样如此。不知道我是否会混淆这个问题。 – Nick

+0

您不能让MicroStrategy决定哪个列用于属性。您可以进行自定义(复杂),也可以为所有可能的日期组合创建过滤器(如“订单日期”=“发票日期”),并在需要时将其添加到报告中,但当然这需要用户知道这些过滤器并知道如何使用它们 – mucio

0

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

它的作品像魅力!

+0

你能详细说明这一点吗?您是否将通用的“日期”层次映射到所有特定的角色播放维度? – Nick