Potresti provare questo:non garantirò che funzionerà meglio, ma è il mio solito modo di correlare una riga con una riga "precedente":
SELECT
* --TODO, list columns
FROM
data d
left join
data d_prev
on
d_prev.time < d.time --TODO - Other key columns?
left join
data d_inter
on
d_inter.time < d.time and
d_prev.time < d_inter.time --TODO - Other key columns?
WHERE
d_inter.time is null AND
(d_prev.value is null OR d_prev.value <> d.value)
(Penso che sia giusto - potrebbe fare con alcuni dati di esempio per convalidarlo).
Fondamentalmente, l'idea è di unire la tabella a se stessa e per ogni riga (in d ), trova le righe candidate (in d_prev ) per la riga "precedente". Quindi fai un altro join, per cercare di trovare una riga (in d_inter ) che esiste tra la riga corrente (in d ) e la riga candidata (in d_prev ). Se non riusciamo a trovare tale riga (d_inter.time is null ), allora quel candidato era effettivamente la riga precedente.