在我们的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:将“三个日期”更改为“两个日期”。
答案 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
...
因此,如果要将两个属性分开,除了在同一个查找上映射它们之外,还应该:
这里的想法是强制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个不同的发票和订单时间层次结构连接到通用层次结构。
它就像魅力一样!