De gemakkelijkste manier om dit te benaderen is het gebruik van variabelen en ik denk dat de gemakkelijkste benadering is om twee variabelen toe te voegen, één het aantal "up"s en de andere het aantal "down"s tot een bepaalde rij. Een gegeven reeks ups heeft een constante waarde voor het aantal voorafgaande "downs" en vice versa. Deze logica kan worden gebruikt voor aggregatie.
De resulterende vraag is:
select result, min(time_stamp) as start_time, max(time_stamp) as end_time
from (select r.*,
(@ups := @ups + (result = 'up')) as ups,
(@downs := @downs + (result = 'down')) as downs
from results r cross join
(select @ups := 0, @downs := 0) vars
where service_id = 1
order by time_stamp
) r
group by result, (case when result = 'up' then downs else ups end);