假设:Range
中的初始数据是连续的; EventDate
均落入由Range
定义的日期范围内。
的关键,下面的方法是要认识到这三个种日期输入数据的 - ValidFrom
,ValidTo
和EventDate
- 有相同结果所需的输出。所需的输出是范围列表,但这些范围的边界日期是平等的,与源范围数据和源事件数据没有区别。
因此,假设该表的结构和样本数据:
DECLARE @Range TABLE (
ValidFrom datetime,
ValidTo datetime,
RangeId int
);
DECLARE @Event TABLE (
EventDate datetime,
EventId int
);
INSERT @Range VALUES
('20100101', '20100501', 1),
('20100501', '20100520', 2),
('20100520', '20170223', 3),
('20170223', '202', 4)
;
INSERT @Event VALUES
('20100315', 101),
('20110415', 102),
('20150515', 103)
;
我们结合来源日期:
WITH RelevantDate (D) AS (
SELECT ValidFrom FROM @Range
UNION
SELECT ValidTo FROM @Range
UNION
SELECT EventDate FROM @Event
)
数他们:
, SequencedDate (D, Sequence) AS (
SELECT D, ROW_NUMBER() OVER (ORDER BY D)
FROM RelevantDate
)
,并产生输出:
SELECT
D1.D AS ValidFrom,
D2.D AS ValidTo,
D1.Sequence AS RangeId
FROM
SequencedDate D1
INNER JOIN SequencedDate D2 ON D1.Sequence + 1 = D2.Sequence
;
这产生的,其目的是Range
个列表替换现有Range
数据:
ValidFrom ValidTo RangeId
----------------------- ----------------------- --------------------
2010-01-01 00:00:00.000 2010-03-15 00:00:00.000 1
2010-03-15 00:00:00.000 2010-05-01 00:00:00.000 2
2010-05-01 00:00:00.000 2010-05-20 00:00:00.000 3
2010-05-20 00:00:00.000 2011-04-15 00:00:00.000 4
2011-04-15 00:00:00.000 2015-05-15 00:00:00.000 5
2015-05-15 00:00:00.000 2017-02-23 00:00:00.000 6
2017-02-23 00:00:00.000 2020-12-31 00:00:00.000 7
应该结果保留原始RangeIds或ID范围只应是唯一的。例如在你的情况下,你的2个事件是否有RangeIds 1和2,其他所有的都转换为3,4,5? – vitalygolub
有多少事件可能落在现有范围内有任何硬限制?是最多两个,还是可以有一个不确定的数字? – AakashM
RangeIds无关紧要,事件数量没有硬性限制。 –