T-SQL - 随时间跟踪事件

时间:2017-05-17 15:11:57

标签: sql tsql date dimensional-modeling

我有一些与ValidFromValidTo日期相关的数据。简单来说:

MembershipId | ValidFromDate | ValidToDate
==========================================
0001         | 1997-01-01    | 2006-05-09
0002         | 1997-01-01    | 2017-05-12
0003         | 2005-06-02    | 2009-02-07

此表上有一个非聚集索引,其中包含两个日期作为键值。

我还有一个日期维度表,涵盖从19002999的每个日期。

我正在试图弄清楚如何从日期维度表中选择一系列日期(比方说2016-01-012016-12-31)然后确定每个日期的会员数是多少在该日期有效。

下面的代码可以完成工作,但性能不是很好,我想知道是否有人建议更好地解决这个问题?

SELECT 
   d.DateKey
  ,(SELECT COUNT(*) FROM Memberships AS m
    WHERE d.DateKey between m.ValidFromDateKey and m.ValidToDateKey
    ) AS MembershipCount

FROM       
   DIM.[Date] AS d

WHERE
   d.CalendarYear = 2016

提前感谢任何建议!

1 个答案:

答案 0 :(得分:5)

你的SQL中的逻辑大多是正确的,你刚刚为SQL的喜欢做的事情做得不好。从您已经完成的Dates表开始,而不是对每行数据进行子选择,将您的逻辑更改为join并且您就在那里:

select d.DateKey
      ,count(m.MembershipID) as MembershipCount
from DIM.[Date] as d
    left join Memberships as m
        on(d.DateKey between m.ValidFromDateKey and m.ValidToDateKey)
where d.CalendarYear = 2016
group by d.DateKey
order by d.DateKey;

您可能需要注意的是确定每天要计算哪些会员资格。例如,如果您的日期为2006-05-09,那么会在当天结束时包含MembershipID 0001吗?

问题基本上是,你计算一整天在任何一点活跃的会员数量,还是只计算在特定时间活跃的会员数量,比如说开始或结束当天?

然后对您的ValidFromDate值重复此思维过程。