如何计算每个日历日的价值?

How to calculate value for each calendar day?

数据样本:

IF OBJECT_ID('tempdb..#Data1') IS NOT NULL DROP TABLE #Data1
GO
create table #Data1 (ControlNo int, ClaimID int, DateCreated date, loss money)
insert into #Data1 values (51294, 54986,'2019-07-24', 3000),
                          (51294, 54986,'2019-07-25', 2963.41),
                          (51294, 54986,'2019-07-26', 2963.41),
                          (51294, 54986,'2019-08-19', 2963.41),
                          (51294, 54986,'2019-08-22', 2963.41),
                          (51294, 55027,'2019-07-25', 929),
                          (51294, 55027,'2019-07-26', 929),
                          (51294, 55027,'2019-08-19', 929),
                          (51294, 55027,'2019-08-22', 929)
select * from #Data1

日历Table:

DECLARE @MinDate DATE = CAST(DATEADD(YY, -1, getdate()) as DATE),  -- a year from today
        @MaxDate DATE =  CAST(GETDATE() as DATE);
;WITH cte_Calendar AS (
SELECT  TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
        Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate)

FROM    sys.all_objects a
        CROSS JOIN sys.all_objects b
) select *  into #Calendar from  cte_Calendar
select  * from #Calendar

每个 ControlNo 可以有多个 ClaimID、唯一的 DateCreated 和 Loss amount,告诉我们在特定日期(时间点)我们有多少损失

我还有一个日历 table,其中有 Date 字段从今天的日期往前 365 天。例如,如果今天是 08/24/2019,那么日历 table 将从 08/24/2018 开始直到 08/24/2019

我如何编写一个查询,使每天 return 从第一个 DateCreated (2019-07-24) 开始直到最后一个 DateCreated (2019-08-22) 和损失需要用 ControlNoDateCreated.

求和

或者我应该说对于每个日历日期我需要每个 ClaimIDDateCreated

的损失总和

所以日历日期 2019-07-24 我们只有 $3,000 对于日期“2019-07-25”,我们有两项索赔:ClaimID 54986 为 2,963.41 美元,ClaimID 55027 为 929 美元,这为我们提供了该日期的总额和 ControlNo 3,892.41 美元 等等...

所以结果应该 return 3 列:日历 DateControlNoLoss

不确定它的效率,但你可以测试一下:

with 
  cal as (
    select d.controlno, c.date
    from #Calendar c cross join (
      select distinct controlno from #Data1 
    ) d
  ),
  cte as (
    select c.controlno, c.date, sum(d.loss) loss
    from cal c left join #Data1 d
    on d.controlno = c.controlno and d.datecreated = c.date
    group by c.controlno, c.date
  )
select c.controlno, c.date, 
  coalesce(c.loss,
    (
      select cc.loss from cte cc 
      where cc.controlno = c.controlno and cc.date = (
        select max(date) from cte
        where controlno = c.controlno and date < c.date and loss is not null
      )
    )
  )
from cte c 

参见demo