具有开始时间和结束时间的SQL事件,转换为小时到班次

时间:2015-05-05 04:21:47

标签: sql sql-server

我在使用Microsoft SQL Server时遇到了麻烦。我有一个表格,其中包含以秒为单位的启动时间列,例如7200(班次2小时)和结束时间和持续时间。

我需要按小时对事件持续时间进行分组。

我的查询目前是:

SELECT
     e.eqmtid as LoadUnit
    ,r.name as Reason
    ,e.starttime 
    ,e.endtime
    ,e.duration

FROM 
    sh_status_events e

INNER JOIN
    PIT_ReasonCodes r
    ON e.reason = r.reason

WHERE 
    e.shiftindex >= <STARTSHIFTINDEX>
    AND e.shiftindex <= <ENDSHIFTINDEX>

返回结果:

LoadUnit    Reason  starttime   endtime duration
EX022   OPERATING   0           1008    1008
EX022   OPERATING   1008        2898    1890
EX022   OPERATING   2898        3535    637
EX022   OPERATING   3615        4515    900
EX022   OPERATING   4515        4541    26
EX022   OPERATING   4885        5555    670

但我需要按小时分组:

Hour        Reason       Duration
1stHour     Operating    2400
2ndHour     Operating    1000
3rdHour     Operating    3200
4thHour     Operating    3600
5thHour     Operating    3600
6thHour     Operating    1322

我能做什么,但对于任何从一小时开始并在另一小时结束的事件,它不会将时间带到下一个小时。

e.g。活动开始于90分钟,持续1小时,应该

2ndHour     Operating    1800
3rdHour     Operating    3600

但它会将完整的5400放入第二个小时。

有没有任何可以解决这个问题的方法?

1 个答案:

答案 0 :(得分:0)

首先,您需要确定总小时数。你可以使用MAX(endtime)CEILING来做到这一点。这样的事情(SELECT CEILING(MAX(endTime) /3600.0) FROM @LoadUnit)。然后,您可以使用CTE或数字表获取开始和结束时间。

然后我们可以使用CROSS APPLY来获得您想要的内容。这样的事情SQL Fiddle

示例数据

DECLARE @LoadUnit TABLE (LoadUnit CHAR(5),Reason VARCHAR(20),starttime INT,endtime INT, duration INT)

INSERT INTO @LoadUnit VALUES
('EX022','OPERATING',   0,           1008,    1008),
('EX022','OPERATING',   1008,        2898,    1890),
('EX022','OPERATING',   2898,        3535,    637),
('EX022','OPERATING',   3615,        4515,    900),
('EX022','OPERATING',   4515,        4541,    26),
('EX022','OPERATING',   4885,        5555,    670);

<强>查询

DECLARE @MaxCeiling INT = (SELECT CEILING(MAX(endTime) /3600.0) FROM @LoadUnit)
;WITH Hrs as 
(
    SELECT 1 hrs,0 as StartTime,3599 as EndTime
    UNION ALL SELECT hrs + 1,StartTime + 3600,EndTime + 3600 from Hrs WHERE hrs + 1 <= @MaxCeiling
)
SELECT H2.hrs,Reason,SUM(H2.endtime - H2.starttime) as Duration
FROM @LoadUnit L
CROSS APPLY 
(
SELECT H.hrs,
CASE WHEN L.starttime < H.StartTime THEN H.StartTime ELSE L.starttime END StartTime,
CASE WHEN L.endtime > H.endtime THEN H.Endtime ELSE L.Endtime END endTime
FROM hrs H
)H2
WHERE H2.endtime - H2.starttime >=0
GROUP BY H2.hrs,Reason