如何将sql日期范围转换为Daily Row

时间:2017-05-22 12:12:56

标签: sql

如何转换日期范围,以便每天为1行,包含当天的开始和结束时间?

I looked at this post about date ranges to row - 但这是一个不同的问题。上面链接的另一个解决方案并没有给出每天从开始到结束的时间 - 因此不允许进行占空因数或利用率计算,以及甘特图的构建。

我们将有一个ID字段,一个开始日期和一个结束日期作为我们的基表。我们希望将其转换为包含每天的ID字段,以及该范围内消耗的时间。

在将开始和结束日期转换为每日工作因素以及设备利用率等其他一些需求时,这非常有用。

1 个答案:

答案 0 :(得分:0)

我从这个社区得到了很多帮助。我想把最终的SQL脚本放在这里供其他人使用。

WITH cte ([VID],[StartTime],[EndTime])  AS 
    ( SELECT   tbl.[ID] as 'VID'
              ,CONVERT(VARCHAR(19), tbl.[StartDT], 120) AS 'StartTime'
              ,CASE 
                 WHEN tbl.[EndDT] <= CONVERT(VARCHAR(11), tbl.[StartDT]+1, 120) + '00:00:00' THEN CONVERT(VARCHAR(19), tbl.[EndDT], 120)
                 ELSE CONVERT(VARCHAR(11), tbl.[StartDT]+1, 120) + '00:00:00'
               END as 'EndTime'
       FROM [SourceTable] as tbl
       WHERE DATEDIFF(DAY,tbl.[StartDT],tbl.[EndDT] )<=365

       UNION ALL

       SELECT  tbl.[ID] as 'VID'
              ,CONVERT(VARCHAR(11), DATEADD(DAY, 1, cte.[StartTime]), 120) + '00:00:00' AS 'StartTime'
              ,CASE
                 WHEN CONVERT(VARCHAR(19), tbl.[EndDT], 120) < CONVERT(VARCHAR(11), DATEADD(DAY, 2, cte.[StartTime]), 120) + '00:00:00'
                 THEN CONVERT(VARCHAR(19), tbl.[EndDT], 120)
                 ELSE CONVERT(VARCHAR(11), DATEADD(DAY, 2, cte.[StartTime]), 120) + '00:00:00'
               END AS 'EndTime'
        FROM cte
           INNER JOIN [SourceTable] as tbl
               ON cte.VID = tbl.ID 
        WHERE CONVERT(VARCHAR(11), cte.[StartTime], 120) < CONVERT(VARCHAR(11), tbl.[EndDT], 120))

 SELECT VID AS ID
       ,[StartTime]
       ,[EndTime]
       ,DateDiff (second,[StartTime],[EndTime]) / 3600  As 'Hours'
       ,DateDiff (second,[StartTime],[EndTime])/60 % 60 as 'Minutes'
       ,((DateDiff (Second,[StartTime],[EndTime]) / 3600)*60)+(DateDiff (second,starttime,endtime)/60 % 60) as 'Total Minutes'
       ,DATEPART(week,[StartTime]) AS weeknum
       ,MONTH([StartTime]) AS MonthNumber
       ,DATENAME(month,[StartTime]) AS MonthName

  FROM cte order by Id, [StartTime]
  option (maxrecursion 0);