Най-лесният начин да се подходи към това е използването на променливи и мисля, че най-лесният подход е да добавите две променливи, едната е броя на "нагоре", а другата - броя на "надолу" до всеки даден ред. Дадена последователност от възходи има постоянна стойност за броя на предходните "надолу" и обратно. Тази логика може да се използва за агрегиране.
Получената заявка е:
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);