数据库 |将跨越日期范围的记录连接到日历以将元素分发到日历箱中
MSSQL | Joining records that span a date range to a Calendar to distribute the element into the Calendar bins
美好的一天,
资料:我有一个日历table,有月粮。摘录:
ID StartDate EndDate Year Month
1 2000-01-01 2000-01-31 2000 200001
2 2000-02-01 2000-02-29 2000 200002
3 2000-03-01 2000-03-31 2000 200003
4 2000-04-01 2000-04-30 2000 200004
5 2000-05-01 2000-05-31 2000 200005
然后我有一个任务 table,其中记录由一个 TaskId、一个任意开始日期、任意结束日期和许多属性组成。示例摘录:
TaskId Start End Attr1 Attr2 Attr3
1 2025-03-13 2026-11-27 1 2 3
2 2027-08-19 2030-02-21 4 5 6
3 2017-06-04 2018-07-30 7 8 9
我想要的输出如下:
TaskId Month Start End DaysInPeriod Attr1 Attr2 Attr3
1 202503 2025-03-13 2025-03-31 19 1 2 3
1 202504 2025-04-01 2025-04-30 30 1 2 3
.
.
1 202611 2026-11-01 2026-11-27 27 1 2 3
到目前为止,我能够获得每个任务的开始月份和结束月份,但我努力实现在整个范围内分配任务所需的逻辑飞跃。
试试这个:
SELECT
t.TaskId,
c.[Month],
CASE WHEN t.Start>c.StartDate THEN t.Start ELSE c.StartDate END as Start,
CASE WHEN t.[End]<c.EndDate THEN t.[End] ELSE c.EndDate END as [End],
DATEDIFF(day,CASE WHEN t.Start>c.StartDate
THEN t.Start ELSE c.StartDate END,
CASE WHEN t.[End]<c.EndDate
THEN t.[End] ELSE c.EndDate END)
+1
as DaysInPeriod,
t.Attr1,
t.Attr2,
t.Attr3
FROM Tasks as t
JOIN calendar as c on
c.EndDate BETWEEN t.Start AND t.[End]
OR c.StartDate BETWEEN t.Start AND t.[End]
OR t.Start BETWEEN c.StartDate AND c.EndDate
OR t.[End] BETWEEN c.StartDate AND c.EndDate
美好的一天,
资料:我有一个日历table,有月粮。摘录:
ID StartDate EndDate Year Month
1 2000-01-01 2000-01-31 2000 200001
2 2000-02-01 2000-02-29 2000 200002
3 2000-03-01 2000-03-31 2000 200003
4 2000-04-01 2000-04-30 2000 200004
5 2000-05-01 2000-05-31 2000 200005
然后我有一个任务 table,其中记录由一个 TaskId、一个任意开始日期、任意结束日期和许多属性组成。示例摘录:
TaskId Start End Attr1 Attr2 Attr3
1 2025-03-13 2026-11-27 1 2 3
2 2027-08-19 2030-02-21 4 5 6
3 2017-06-04 2018-07-30 7 8 9
我想要的输出如下:
TaskId Month Start End DaysInPeriod Attr1 Attr2 Attr3
1 202503 2025-03-13 2025-03-31 19 1 2 3
1 202504 2025-04-01 2025-04-30 30 1 2 3
.
.
1 202611 2026-11-01 2026-11-27 27 1 2 3
到目前为止,我能够获得每个任务的开始月份和结束月份,但我努力实现在整个范围内分配任务所需的逻辑飞跃。
试试这个:
SELECT
t.TaskId,
c.[Month],
CASE WHEN t.Start>c.StartDate THEN t.Start ELSE c.StartDate END as Start,
CASE WHEN t.[End]<c.EndDate THEN t.[End] ELSE c.EndDate END as [End],
DATEDIFF(day,CASE WHEN t.Start>c.StartDate
THEN t.Start ELSE c.StartDate END,
CASE WHEN t.[End]<c.EndDate
THEN t.[End] ELSE c.EndDate END)
+1
as DaysInPeriod,
t.Attr1,
t.Attr2,
t.Attr3
FROM Tasks as t
JOIN calendar as c on
c.EndDate BETWEEN t.Start AND t.[End]
OR c.StartDate BETWEEN t.Start AND t.[End]
OR t.Start BETWEEN c.StartDate AND c.EndDate
OR t.[End] BETWEEN c.StartDate AND c.EndDate