如果我正确理解了您的问题,您已经创建了多个日期属性(具有不同的逻辑含义),并且它们映射到日历表的不同别名上。
除非用户在他们的报告中使用不同的单一事实表,否则没有问题,但是当他们使用来自销售和发票的指标/事实时,您会获得成倍的结果,因为“订单日期”和“发票日期”是不同的属性。
您的 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 将使用它从父属性转到事实表。
希望这可以帮助您摆脱困境。