【问题标题】:TSQL: split value in timeTSQL:及时拆分值
【发布时间】:2017-05-23 16:30:54
【问题描述】:

我有一个基本表 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.

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    您可以像这样使用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

    【讨论】:

    • 谢谢;完成最终选择 SELECT t.start_date ,t.end_date ,datediff(MINUTE, t.start_date, t.end_date) AS duration_min ,part.value_s ,cast((datediff(MINUTE, t.start_date, t.end_date)) / cast( (part.value_s) AS DECIMAL(15, 8)) AS DECIMAL(15, 8)) * cast(t.value AS DECIMAL(15, 8)) AS FINAL_VALUE ,t.task ,t.value FROM TEMP t LEFT JOIN ( SELECT tt.task ,sum(datediff(MINUTE, tt.start_date, tt.end_date)) AS value_s FROM TEMP tt GROUP BY tt.task ) part ON t.task = part.task ORDER BY t.task OPTION (MAXRECURSION 0 )
    • 我认为最重要的是解决您的问题的“方法”,而不是完全回答。无论如何,谢谢分享...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    相关资源
    最近更新 更多