T-SQL - 跟踪随时间发生的事件

T-SQL - Track occurrences over time

我有一些数据关联了 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

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

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

我想弄清楚如何 select 日期维度 table 的日期范围(比方说 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

提前感谢您的任何建议!

您 SQL 中的逻辑大部分是正确的,您只是因为 SQL 喜欢做事的方式而执行得不好。从您已经完成的 Dates table 开始,而不是为每一行数据做一个子 select,将您的逻辑更改为 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 值重复此思考过程。