我有一个包含2个日期字段和一个标识符(id,fromdate和todate)的表格。这些日期以任何可能的方式重叠。我需要生成一个段列表,每个段都有一个描述该列表中不同段的开始和结束日期。
例如:
id, FromDate ToDate
1, 1944-12-11, 1944-12-31
2, 1945-01-01, 1945-12-31
3, 1945-01-01, 1945-06-30
4, 1945-12-31, 1946-05-01
5, 1944-12-17, 1946-03-30
应该产生所有重叠的所有部分:
1, 1944-12-11, 1944-12-16
1, 1944-12-17, 1944-12-31
5, 1944-12-17, 1944-12-31
2, 1945-01-01, 1945-06-30
3, 1945-01-01, 1945-06-30
5, 1945-01-01, 1945-06-30
2, 1945-07-01, 1945-12-09
5, 1945-07-01, 1945-12-09
2, 1945-12-10, 1945-12-31
4, 1945-12-10, 1945-12-31
5, 1945-12-10, 1945-12-31
4, 1946-01-01, 1946-03-30
5, 1946-01-01, 1946-03-30
4, 1946-04-01, 1946-05-01
或者图表可能有帮助
INPUT
1 <---->
2 <----------->
3 <----->
4 <---------->
5 <----------------->
OUTPUT
1 <->
1 <->
5 <->
2 <----->
3 <----->
5 <----->
2 <->
5 <->
2 <->
4 <->
5 <->
4 <->
5 <->
4 <---->
请帮忙
答案 0 :(得分:2)
You can use this SO question's answer as a basis
它分成了这个输出,但我认为很容易变成你需要的东西:
OUTPUT
1 <->
1,5 <->
2,3,5 <----->
...
This link should also prove helpful - 它仅显示如何构建范围。
答案 1 :(得分:0)
尝试以下脚本
SCHEMA :
CREATE TABLE splitDates
([member] int, effdt datetime, termdt datetime)
;
INSERT INTO splitDates
([member], effdt, termdt)
VALUES
(1, '1944-12-11', '1944-12-31'),
(2, '1945-01-01', '1945-12-31'),
(3, '1945-01-01', '1945-06-30'),
(4, '1945-12-31', '1946-05-01'),
(5, '1944-12-17', '1946-03-30');
SQL脚本:
DECLARE @SplitRanges TABLE ([member] int, theDate datetime, des varchar(10));
INSERT INTO @SplitRanges
SELECT DISTINCT
m.member,
memDt.theDate,
memdt.des
FROM splitDates m
JOIN ( SELECT DISTINCT effdt as theDate,'effdt' des FROM splitDates
union all
SELECT DISTINCT effdt-1 as theDate,'trmdt' des FROM splitDates
union all
SELECT DISTINCT termdt as theDate,'trmdt' des FROM splitDates
union all
SELECT DISTINCT termdt+1 as theDate,'effdt' des FROM splitDates
) as memDt on 1=1
WHERE memDt.theDate >= m.effdt
AND memDt.theDate <= m.termdt
ORDER BY m.member, memdt.thedate;
;WITH rowNumbers as (
SELECT ef.member, ef.thedate,ef.des,
ROW_NUMBER() over (PARTITION BY ef.member ORDER BY ef.thedate ASC) AS rn
FROM @SplitRanges ef
)
SELECT DISTINCT ef.member, ef.thedate as effdt, tm.thedate as termdt FROM rowNumbers ef
JOIN rownumbers tm on tm.member=ef.member and ef.rn+1=tm.rn
WHERE ef.des='effdt'
order by ef.thedate
输出:
member effdt termdt
1 1944-12-11 00:00:00.000 1944-12-16 00:00:00.000
1 1944-12-17 00:00:00.000 1944-12-31 00:00:00.000
5 1944-12-17 00:00:00.000 1944-12-31 00:00:00.000
2 1945-01-01 00:00:00.000 1945-06-30 00:00:00.000
3 1945-01-01 00:00:00.000 1945-06-30 00:00:00.000
5 1945-01-01 00:00:00.000 1945-06-30 00:00:00.000
2 1945-07-01 00:00:00.000 1945-12-30 00:00:00.000
5 1945-07-01 00:00:00.000 1945-12-30 00:00:00.000
2 1945-12-31 00:00:00.000 1945-12-31 00:00:00.000
4 1945-12-31 00:00:00.000 1945-12-31 00:00:00.000
5 1945-12-31 00:00:00.000 1945-12-31 00:00:00.000
4 1946-01-01 00:00:00.000 1946-03-30 00:00:00.000
5 1946-01-01 00:00:00.000 1946-03-30 00:00:00.000
4 1946-03-31 00:00:00.000 1946-05-01 00:00:00.000