Der einfachste Weg, dies zu erreichen, ist die Verwendung von Variablen, und ich denke, der einfachste Ansatz besteht darin, zwei Variablen hinzuzufügen, eine die Anzahl der "Ups" und die andere die Anzahl der "Downs" bis zu einer bestimmten Zeile. Eine gegebene Aufwärtsfolge hat einen konstanten Wert für die Anzahl vorangehender "Abwärts" und umgekehrt. Diese Logik kann für die Aggregation verwendet werden.
Die resultierende Abfrage lautet:
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);