На это не ответят чем-то первозданной красоты, по крайней мере, насколько я знаю.
Хотя это не так сложно сделать. Однако вы должны подружиться с аналитическими функциями. в данном случае: Lag and Lead.
Если это то, что вы хотите получить (я уверен, что вы можете сами вычислить разницу, интересная часть - получить диапазоны), тогда проверьте запрос ниже:
10:00 A 100
10:05 A 0 10:05 10:25
10:10 A 0 10:05 10:25
10:15 A 0 10:05 10:25
10:20 A 0 10:05 10:25
10:25 A 0 10:05 10:25
10:30 A 100
10:35 A 0 10:35 10:40
10:40 A 0 10:35 10:40
10:45 A 100
10:50 A 100
10:55 A 0 10:55 10:55
11:00 A 100
11:05 A 0 11:05 11:05
with startTime as
(
SELECT time
,Name
,case
when t.availability = 0 and
/* see the default value passed to "lag",
if nothing gets returned (first row), we return 2 which is > 0 */
lag(availability, 1,2) OVER(partition BY Name ORDER BY time) > 0 then
time
end start_time
FROM SampleTable t
)
,stopTime as
(
SELECT time
,name
,case
when t.availability = 0 and
/* see the default value passed to "lead"
if nothing gets returned (last row), we return 2 which is > 0*/
(lead(availability, 1, 2) OVER(partition BY Name ORDER BY time) > 0) then
time
end stop_time
FROM SampleTable t
)
SELECT t.time
,t.Name
,t.availability
,case
when t.availability = 0 then
(SELECT Max(start_time)
FROM startTime
WHERE start_time is not null
and time <= t.time)
end as start_time
,case
when t.availability = 0 then
(SELECT Min(stop_time)
FROM stopTime
WHERE stop_time is not null
and time >= t.time)
end as stop_time
FROM SampleTable t
ORDER BY t.time