Masalah Anda tampaknya adalah bahwa rentang waktu perlu dipecah dalam hitungan jam. Jadi, Anda harus mulai dengan semua jam dalam sehari. Kemudian Anda menghitung tumpang tindih, menjumlahkan perbedaannya (di bawah dalam milidetik) dan mengonversi semuanya kembali ke waktu untuk output.
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
Juga, untuk membuat ini berfungsi, Anda perlu membungkus "mulai" dan "akhir" dalam tanda kutip ganda atau tanda kurung siku. Ini adalah kata-kata yang dicadangkan dalam T-SQL. Dan Anda perlu mengganti "..." dengan jalur tambahan selama berjam-jam dari 3 hingga 22.