Về cơ bản, để giải quyết vấn đề này, bạn chỉ cần một danh sách các số.
with nums as (
select 0.0 as n from dual
union all
select n + 1
from nums
where n < 100
)
select trunc(t.startdate + n * 1/ 24, 'hh'),
sum((case when trunc(t.startdate + n * 1/24, 'hh') = trunc(t.startdate, 'hh')
then 60 - extract(minute from startdate)
else 0
end) +
(case when trunc(t.startdate + n * 1/24, 'hh') > trunc(t.startdate, 'hh') and
trunc(t.startdate + n * 1/24, 'hh') < trunc(t.enddate, 'hh')
then 60
else 0
end) +
(case when trunc(t.startdate + n * 1/24, 'hh') = trunc(t.enddate, 'hh')
then extract(minute from enddate)
else 0
end)
) as minutes
from table t join
nums n
where trunc(t.startdate + n * 1/24, 'hh') <= t.enddate;
Điều này hoạt động cho sự khác biệt lên đến 100 giờ trong các ngày. Bạn có thể điều chỉnh 100
cho nhu cầu của bạn. Bạn thậm chí có thể sử dụng một truy vấn con để nhận được giá trị tối đa phù hợp.
Có một số thủ thuật có thể đơn giản hóa logic. Tôi nghĩ rằng logic trên là rõ ràng nhất. Nó chu kỳ qua các giờ. Nếu giờ được so sánh là giờ đầu tiên, hãy sử dụng 60 phút. Nếu cuối cùng, hãy sử dụng số phút. Nếu không, hãy sử dụng 60.