我有两张时间维度表
日期(每天独特的行)
一天中的时间(一天中每分钟的唯一行)
如果想要检索最后X小时的事实,其中X可以是任何大于0的数字,那么在给定此模式的情况下,查询会是什么样子。
当开始时间和结束时间恰好出现在一年中的两个不同日期时,事情开始变得棘手。
编辑:我的事实表没有时间戳列
答案 0 :(得分:2)
事实表确实具有(并且应该具有)原始时间戳,以避免在一天的边界上发生的奇怪的按时查询。奇怪的是在WHERE子句中有一些复杂的日期时间函数。
在大多数DW中,这些类型的查询非常罕见,但您似乎将数据流式传输到DW并同时使用它进行报告。
所以我建议:
在事实表中引入完整时间戳。
对于旧记录,请从日期和时间键重新创建时间戳。
DW查询都是关于没有 WHERE子句中的任何函数,或者如果必须使用函数,请确保它是SARGABLE。
答案 1 :(得分:0)
将Start Date
和End Date
列转换为TIMESTAMP
并填充它们可能会更好。
切片表需要选择适当的interval BETWEEN Start Date AND End Date
。在Oracle中,interval
将与SYSDATE - (4/24)
或SYSDATE - NUMTODSINTERVAL(4, 'HOUR')
这也可以改写为:
Start Date <= (SYSDATE - (4/24)) AND End Date >= (SYSDATE - (4/24))
答案 2 :(得分:0)
在我看来,根据您拥有的当前架构,您需要从时间维度表中检索符合搜索条件的相应时间ID,然后在事实表中搜索匹配的行。根据时间维度的粒度,您可能需要检查执行的性能(SQL Server示例):
子选择:
从FOO WHERE TIMEID中选择X(从DIMTIME中选择ID,其中&gt; = DATEPART(HOUR,CURRENT_TIMESTAMP())和DATEID IN(SELECT ID from DIMDATE WHERE DATE = GETDATE())
内部联接:
选择X FROM FOO INNER JOIN DIMTIME ON TIMEID = DIMTIME.ID WHERE HOUR&GT = DATEPART(HOUR,CURRENT_TIMESTAMP())INNER JOIN DIMDATE ON DATEID = DIMDATE.ID WHERE DATE = GETDATE()
这些都不是真正有吸引力的选择。
您是否认为您可能正在查询用于汇总分析的多维数据集,而不一定要查询“最后X”分析?
如果这不是一个“累积”立方体,我会同意其他海报,因为你应该用更好的密钥重新标记你的事实表,如果你确实打算经常搜索小时,您可能应该在事实表中包含它,因为任何其他尝试都可能使查询不可搜索(请参阅What makes a SQL statement sargable?)。
Microsoft建议http://msdn.microsoft.com/en-us/library/aa902672%28v=sql.80%29.aspx:
与其他维度表中使用的代理键相比,日期和时间维度键应该是“智能”。日期维度的建议密钥的形式为“yyyymmdd”。用户可以轻松地记住此格式并将其合并到查询中。它也是按日期划分为多个表的事实表的推荐代理键格式。
祝你好运!