Den nemmeste måde at nærme sig dette på er at bruge variabler, og jeg tror, den nemmeste tilgang er at tilføje to variable, den ene antallet af "op" og den anden antallet af "ned" op til en given række. En given sekvens af ups har en konstant værdi for antallet af foregående "downs" og omvendt. Denne logik kan bruges til aggregering.
Den resulterende forespørgsel er:
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);