La façon la plus simple d'aborder cela consiste à utiliser des variables et je pense que l'approche la plus simple consiste à ajouter deux variables, l'une le nombre de "up" et l'autre le nombre de "down" jusqu'à une ligne donnée. Une séquence donnée de hauts a une valeur constante pour le nombre de "bas" précédents, et vice versa. Cette logique peut être utilisée pour l'agrégation.
La requête résultante est :
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);