数据库 |将跨越日期范围的记录连接到日历以将元素分发到日历箱中

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