SQL按小时和天计算的持续时间

时间:2015-08-17 09:27:29

标签: sql sql-server

我正在尝试编写一个查询,将持续时间字段转换为秒,然后根据时间和日期对持续时间求和。

持续时间是“事件”在结束日期的小时内运行的时间。

我有这个:

Description | Start Date              | End Date                | Duration
---------------------------------------------------------------------------
ABC         | 2015-08-17 10:30:30.000 | 2015-08-17 11:59:59.000 | 0 00:59:59.0
ABC         | 2015-08-18 11:00:00.000 | 2015-08-18 11:30:00.000 | 0 00:30:00.0
DEF         | 2015-08-17 08:25:00.000 | 2015-08-17 10:30:00.000 | 0 00:30::00.0
ABC         | 2015-08-18 11:30:00.000 | 2015-08-18 11:59:59.000 | 0 00:29:59.0

我正试图得到这样的东西:

Description | Date       | Hour | Duration
-------------------------------------------
ABC         | 2015-08-17 | 11   | 3575
ABC         | 2015-08-18 | 11   | 3575
DEF         | 2015-08-17 | 10   | 1800

这是我写过的查询:

SELECT Description,
       DATEPART(HOUR, EndDT), SUM(DATEPART(SECOND, CONVERT(TIME, RIGHT(Duration, LEN(Duration) -2))) +
       60 * DATEPART(MINUTE, CONVERT(TIME, RIGHT(Duration, LEN(Duration) - 2))) +
       3600 * DATEPART(HOUR, CONVERT(TIME, RIGHT(Duration, LEN(Duration) - 2))))
FROM table
GROUP BY Description,
         DATEPART(HOUR, EndDT),
         DATEADD(d, 0, DATEDIFF(d, 0, EndDT));

这个查询似乎没有像我想的那样考虑几天,我不知道如何修复它。

我得到的是这样的东西:

Description | Hour | Duration
------------------------------
ABC         | 11   | 7150
DEF         | 10   | 1800

我也意识到我目前没有在select语句中找到日期,但可以在以后添加。

2 个答案:

答案 0 :(得分:1)

这可以显示每个事件每天运行的小时数和秒数。

SELECT Description,
DATEDIFF(s,MIN([Start Date]), MAX([End Date]))/60/60 AS Hour,
DATEDIFF(s,MIN([Start Date]), MAX([End Date])) AS Duration
FROM yourtable
GROUP BY Description, DAY([Start Date])

输出

Description  Hour   Duration
ABC          1      5369
DEF          2      7500
ABC          0      3599

SQL小提琴:http://sqlfiddle.com/#!3/935c7/15/0

答案 1 :(得分:1)

如果您仅通过EndDT日期部分GROUP数据,则可获得所需内容:

WITH T AS (
    SELECT *
    FROM (VALUES('ABC', CAST('2015-08-17 10:30:30.000' AS DATETIME), CAST('2015-08-17 11:59:59.000' AS DATETIME), '0 00:59:59.0'),
                ('ABC', CAST('2015-08-18 11:00:00.000' AS DATETIME), CAST('2015-08-18 11:30:00.000' AS DATETIME), '0 00:30:00.0'),
                ('DEF', CAST('2015-08-17 08:25:00.000' AS DATETIME), CAST('2015-08-17 10:30:00.000' AS DATETIME), '0 00:30:00.0'),
                ('ABC', CAST('2015-08-18 11:30:00.000' AS DATETIME), CAST('2015-08-18 11:59:59.000' AS DATETIME), '0 00:29:59.0'))
            AS V(Description, StartDT, EndDT, Duration)
) 
SELECT  Description ,
        CAST(EndDT AS DATE),
        DATEPART(HOUR, EndDT) ,
        SUM(DATEPART(SECOND, CONVERT(TIME, RIGHT(Duration, LEN(Duration) - 2)))
            + 60 * DATEPART(MINUTE,CONVERT(TIME, RIGHT(Duration, LEN(Duration) - 2)))
            + 3600 * DATEPART(HOUR, CONVERT(TIME, RIGHT(Duration, LEN(Duration) - 2))))
FROM    T
GROUP BY 
        Description ,
        CAST(EndDT AS DATE),
        DATEPART(HOUR, EndDT)

为此我得到了:

ABC 2015-08-17  11  3599
ABC 2015-08-18  11  3599
DEF 2015-08-17  10  1800

您可以忽略保存上述示例数据的CTE,只需将其添加即可提供实际示例。