Vấn đề của bạn dường như là khoảng thời gian cần được chia nhỏ theo giờ. Vì vậy, bạn cần bắt đầu với tất cả các giờ trong ngày. Sau đó, bạn tính toán sự chồng chéo, tổng hợp các chênh lệch (dưới đây tính bằng mili giây) và chuyển đổi mọi thứ trở lại một thời điểm cho kết quả đầu ra.
with const as (
select dateadd(hour, 1, cast(cast(getdate() -1 as date) as datetime)) as midnight
),
allhours as (
select 0 as hour, midnight as timestart, dateadd(hour, 1, midnight) as timeend from const union all
select 1 as hour, dateadd(hour, 1, midnight), dateadd(hour, 2, midnight) from const union all
select 2 as hour, dateadd(hour, 2, midnight), dateadd(hour, 3, midnight) from const union all
. . .
select 23 as hour, dateadd(hour, 23, midnight), dateadd(hour, 24, midnight) from const
)
select ah.hour,
sum(datediff(ms, (case when ah.timestart >= dt.begin then timestart else dt.begin end),
(case when ah.timeend <= dt.end then ah.timeend else dt.end end)
)
) as totalms,
cast(dateadd(ms, sum(datediff(ms, (case when ah.timestart >= dt.begin then timestart else dt.begin end),
(case when ah.timeend <= dt.end then ah.timeend else dt.end end)
)
),
0) as time
) as totalTime
from allhours ah left outer join
DeviceTable dt
on ah.timestart< coalesce(dt.end, getdate()) and
ah.timeend >= dt.begin
group by ah.hour
order by ah.hour
Ngoài ra, để thực hiện công việc này, bạn cần đặt "bắt đầu" và "kết thúc" trong dấu ngoặc kép hoặc dấu ngoặc vuông. Đây là những từ dành riêng trong T-SQL. Và bạn cần thay thế dấu "..." với các dòng bổ sung cho các giờ từ 3 đến 22.