我在使用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放入第二个小时。
有没有任何可以解决这个问题的方法?
答案 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