Convert Date Range to Individual Days

后端 未结 2 1428
终归单人心
终归单人心 2021-01-22 23:12

A table called VolumeRequest stores the volume requests by accounts for a date range.

AccountId   StartDate                       EndDate                    


        
相关标签:
2条回答
  • 2021-01-22 23:39

    I like to use a Dates table such as

    CREATE TABLE #Dates(
        DateId INT,
        CalendarDate DATETIME)
    

    filled with dates for whatever range you need. I use this table to join to tables such as VolumeRequest to retrieve the output you requested.

    SELECT
        v.AccountId,
        d.CalendarDate,
        SUM(v.DailyVolume)
    FROM
        #Dates d INNER JOIN
        VolumeRequest v ON
            d.CalendarDate >= v.StartDate AND
            d.CalendarDate <= v.EndDate
    group by
        d.CalendarDate,
        v.AccountId
    

    to fill the #Dates table, I use something like this:

    declare @startdate datetime = '6/1/13', @enddate datetime = '7/31/13'
    
    create table #Dates(CalendarDate datetime)
    
    insert into #Dates(CalendarDate)
    select
        dateadd(dd, rid-1, @startdate) as calendardate
    from (
        select
            ROW_NUMBER() over(order by o.object_id) as rid
        From
            sys.objects o cross apply
            sys.objects o2
    ) dates
    where
        dateadd(dd, rid-1, @startdate) >= @startdate and dateadd(dd, rid-1, @startdate) <= @enddate
    

    Modify to meet your date range needs.

    0 讨论(0)
  • 2021-01-22 23:49

    SQLFiddle demo

    Using WITH clause and recursion we generate Days table with all days between MIN and MAX dates. Then generate table Accounts with distinct AccountID. Finally JOIN all these tables and group all with SUM.

    WITH MINMAX as 
    ( SELECT MIN(StartDate) as MinDate,
             MAX(EndDate) as MaxDate
      from T
    ),
    DAYS as
    ( SELECT MinDate as D from MINMAX
      UNION ALL
      SELECT D+1 as D FROM DAYS WHERE D+1<=
        (
          SELECT MaxDate FROM MINMAX  
         )
    ),
    Accounts as 
    (
      select distinct AccountID from T
    ) 
    
    select A.AccountId,Days.D,sum(T.DailyVolume) from Days
    CROSS JOIN Accounts A 
    JOIN T on A.AccountID=T.AccountID
              AND
              Days.D between T.StartDate and T.EndDate
    GROUP BY A.AccountId,Days.D
    ORDER BY A.AccountId,Days.D
    OPTION (MAXRECURSION 10000)
    
    0 讨论(0)
提交回复
热议问题