如何在两个日期之间创建开发月日历

问题描述

建筑损失发展三角形我想创建一个日历,该日历将在两个日期之间带来所有可能的发展月份。

在我的数据中,我有两个可用日期:EffectiveDate和TransactionDate。 TransactionDate始终大于EffectiveDate。

所以我正在这样做:

IF OBJECT_ID('tempdb..#Calendar') IS NOT NULL DROP TABLE #Calendar
create table #Calendar (EffDate date,TransactDate date) 
INSERT INTO #Calendar values 
                             ('2019-08-01','2019-11-22'),('2018-02-06','2019-01-16'),('2018-10-22','2019-02-27'),('2018-07-23','2019-03-06'),('2018-03-01','2019-05-10'),('2019-04-09','2020-04-28'),('2019-03-01','2020-05-06'),('2019-06-28','2020-06-22'),('2018-09-26','2020-07-28')
select YEAR(EffDate) as EffYear,YEAR(TransactDate) as TransactYear,CASE WHEN 
            CEILING(  DATEDIFF(DD,DATEFROMPARTS(YEAR(EffDate),12,31),TransactDate) /CONVERT(DECIMAL(4,2),30)) <= 0 THEN 1 
            ELSE CEILING(DATEDIFF(DD,30))  END 
            as DevMonth
from #Calendar

但是如何创建日历表,以便可以LEFT JOIN到它并拥有所有可能的值?

我尝试了类似的方法,但是需要一些时间:

 IF OBJECT_ID('tempdb..#YearCalendar') IS NOT NULL DROP TABLE #YearCalendar
    SELECT TOP (DATEDIFF(DAY,CONVERT(DATE,'2018-01-01'),GETDATE() + 10)))
    'As_Of_Date' = DATEADD(DAY,ROW_NUMBER() OVER(ORDER BY a.object_id) - 1,'2018-01-01'))
into #YearCalendar
FROM sys.all_objects a
CROSS JOIN sys.all_objects b

IF OBJECT_ID('tempdb..#DateCalendar') IS NOT NULL DROP TABLE #DateCalendar

    SELECT TOP (DATEDIFF(DAY,'2018-01-01'))
into #DateCalendar
FROM sys.all_objects a
CROSS JOIN sys.all_objects b



declare @MinYearNum int = (SELECT YEAR(MIN(As_Of_Date)) from #DateCalendar),@MinMonthNum int = (SELECT MONTH(MIN(As_Of_Date)) from #DateCalendar)

select 
* from 
(
select distinct  
Year(b.As_Of_Date) as AsOfYear,(YEAR(a.As_Of_Date) - YEAR(b.As_Of_Date)) * 12 + 12 as PolicyDevYear,CASE WHEN CEILING (
    DATEDIFF(DD,DATEFROMPARTS(YEAR(b.As_Of_Date),a.As_Of_Date) / CONVERT(DECIMAL(4,30) ) <= 0 then 1 else 
    CEILING (
    DATEDIFF(DD,30) ) 
    END AS DevMonth
from  #DateCalendar a
cross join 
(select  [As_Of_Date] =  DATEFROMPARTS(YEAR(As_Of_Date),31) from #YearCalendar) b
) cal
order by AsOfYear,DevMonth

解决方法

此解决方案使用此link中的计数表。对于#Calendar中的每一行,它将生成表中两个日期之间的所有天。

"search.exclude": {
    "**/node_modules": true,"**/bower_components": true,"**/*.code-search": true,"**/projects/project1": true,"**/projects/project2": false
    "**/projects/project3": false
  }

编辑:OP希望在开始日期和当前日期之间设置日期范围。

select 
  YEAR(EffDate) as EffYear,YEAR(TransactDate) as TransactYear,diff.day_diff_count,dateadd(d,t.n,EffDate) all_dt
from
  #Calendar
 cross apply
  (select datediff(D,EffDate,TransactDate) day_diff_count) diff
 cross apply
  dbo.fnTally(0,diff.day_diff_count) t;

结果

drop table if exists #Calendar;
go
create table #Calendar(
  day_dt date unique not null);

declare
  @start_dt         date='2017-01-01',@end_dt           date=getdate();

insert #Calendar(day_dt)
select dateadd(d,@start_dt) all_dt
from
  (select datediff(D,@start_dt,@end_dt) day_diff_count) diff
 cross apply
  dbo.fnTally(0,diff.day_diff_count) t;