Сначала создайте другую таблицу для 24-часового целого числа
CREATE TABLE "HourGroup" (
"H" INT UNIQUE NOT NULL
);
INSERT INTO public."HourGroup"("H")
VALUES
('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'),('10'),('11'),('12'),('13'),('14'),('15'),('16'),('17'),('18'),('19'),('20'),('21'),('22'),('23');
Затем используйте LEAD () для получения данных следующей строки
select
"State",
"Remark",
"StartTime",
LEAD("StartTime",1) over ( order by "StartTime") "EndAt"
from "Process"
Следующее соединение с другой таблицей
select A."State"
,"Remark"
,"StartTime"
,case when DATE_PART('hour',A."StartTime") = B."H" Then A."StartTime" ELSE ( DATE_TRUNC('day',A."StartTime")::timestamp + interval '1 hour'*(B."H")) END as "HourStartTime"
,case when DATE_PART('hour',A."StartTime") = B."H" Then (case when B."H" = DATE_PART('hour',A."EndAt") Then "EndAt" ELSE ( DATE_TRUNC('day',A."EndAt")::timestamp + interval '1 hour'*(B."H"+1)) END) ELSE (case when B."H" < DATE_PART('hour',A."EndAt") Then ( DATE_TRUNC('day',A."EndAt")::timestamp + interval '1 hour'*(B."H"+1)) ELSE "EndAt" END) END as "HourEndTime"
From "previousresult" A
Join "HourGroup" B on "H" between DATE_PART('hour',"StartTime") and DATE_PART('hour',"EndAt")
Окончательный запрос для расчета продолжительности.
select
"State",
"ProcessID",
"Remark",
"StartTime",
"HourStartTime",
"HourEndTime",
SUM(("HourEndTime" - "HourStartTime")) as "Duration"
from cte2
group by "State","ProcessID","Remark","StartTime","HourStartTime","HourEndTime"
order by "StartTime"