T-SQL - 跟踪随时间发生的事件
T-SQL - Track occurrences over time
我有一些数据关联了 ValidFrom
和 ValidTo
日期。简单来说:
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,涵盖从 1900
到 2999
的每个日期。
我想弄清楚如何 select 日期维度 table 的日期范围(比方说 2016-01-01
到 2016-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
值重复此思考过程。
我有一些数据关联了 ValidFrom
和 ValidTo
日期。简单来说:
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,涵盖从 1900
到 2999
的每个日期。
我想弄清楚如何 select 日期维度 table 的日期范围(比方说 2016-01-01
到 2016-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
值重复此思考过程。