How to Determine Values for Missing Months based on Data of Previous Months in T-SQL

前端 未结 7 1715
庸人自扰
庸人自扰 2020-12-09 14:24

I have a set of transactions occurring at specific points in time:

CREATE TABLE Transactions (
    TransactionDate Date NOT NULL,
    TransactionValue Intege         


        
7条回答
  •  被撕碎了的回忆
    2020-12-09 14:38

    John Gibb posted a fine answer, already accepted, but I wanted to expand on it a bit to:

    • eliminate the one year limitation,
    • expose the date range in a more explicit manner, and
    • eliminate the need for a separate numbers table.

    This slight variation uses a recursive common table expression to establish the set of Dates representing the first of each month on or after from and to dates defined in DateRange. Note the use of the MAXRECURSION option to prevent a stack overflow (!); adjust as necessary to accommodate the maximum number of months expected. Also, consider adding alternative Dates assembly logic to support weeks, quarters, even day-to-day.

    with 
    DateRange(FromDate, ToDate) as (
      select 
        Cast('11/1/2008' as DateTime), 
        Cast('2/15/2010' as DateTime)
    ),
    Dates(Date) as (
      select 
        Case Day(FromDate) 
          When 1 Then FromDate
          Else DateAdd(month, 1, DateAdd(month, ((Year(FromDate)-1900)*12)+Month(FromDate)-1, 0))
        End
      from DateRange
      union all
      select DateAdd(month, 1, Date)
      from Dates
      where Date < (select ToDate from DateRange)
    )
    select 
      d.Date, t.TransactionValue
    from Dates d
    outer apply (
      select top 1 TransactionValue
      from Transactions
      where TransactionDate <= d.Date
      order by TransactionDate desc
    ) t
    option (maxrecursion 120);
    

提交回复
热议问题