TSQL:及时拆分值

时间:2017-05-23 07:49:26

标签: sql sql-server tsql

我有一个基本的表dbo.Basic

start_date                end_date                  task     value
----------------------------------------------------------------------------
2016-01-12 13:02:00.000   2016-01-12 17:18:00.000   400001   12675.59370000
2016-01-13 03:09:00.000   2016-01-13 07:48:00.000   400002   13689.93600000
2016-01-13 07:48:00.000   2016-01-13 12:13:00.000   400003   12001.64456400
2016-01-13 12:13:00.000   2016-01-13 20:45:00.000   400004   23189.46598800

我希望按时间(,1分钟粒度)分配最大值。 1小时的间隔

start_date                end_date                  task     value
----------------------------------------------------------------------------
2016-01-12 13:02:00.000   2016-01-12 14:00:00.000   400001   <calculated part of value for 400001>
2016-01-12 14:00:00.000   2016-01-12 15:00:00.000   400001   <calculated part of value for 400001>
2016-01-12 15:00:00.000   2016-01-12 16:00:00.000   400001   ...
2016-01-12 16:00:00.000   2016-01-12 17:00:00.000   400001   ...
2016-01-12 17:00:00.000   2016-01-12 17:18:00.000   400001   ...
2016-01-13 03:09:00.000   2016-01-13 04:00:00.000   400002   <calculated part of value for 400002>
2016-01-13 04:00:00.000   2016-01-13 05:00:00.000   400002  ...
...
etc.

1 个答案:

答案 0 :(得分:3)

您可以使用recursive CTE这样的

DECLARE @SampleData AS TABLE
(
   start_date datetime,
   end_date datetime,
   task int
)

INSERT INTO @SampleData
VALUES
('2016-01-12 13:02:00.000','2016-01-12 17:18:00.000', 400001)  
,('2016-01-13 03:09:00.000','2016-01-13 07:48:00.000', 400002)  
,('2016-01-13 07:48:00.000','2016-01-13 12:13:00.000', 400003)  
,('2016-01-13 12:13:00.000','2016-01-13 20:45:00.000', 400004)

;WITH temp AS 
(
   SELECT sd.start_date, dateadd(hour, datediff(hour,0,sd.start_date) + 1,0) AS end_date, sd.end_date as actual_enddate, sd.task
   FROM @SampleData sd
   UNION ALL
   SELECT  t.end_date, 
         CASE 
            WHEN dateadd(hour, 1,t.end_date) < t.actual_enddate THEN dateadd(hour, 1,t.end_date) 
            ELSE t.actual_enddate 
         END AS end_date,
         t.actual_enddate, 
         t.task
   FROM temp t
   WHERE t.end_date != t.actual_enddate
)
SELECT t.start_date,t.end_date,t.task
FROM temp t
ORDER BY t.task 
OPTION (MAXRECURSION 0)

演示链接:http://rextester.com/GQN93710