Vous pouvez essayer ceci - je ne vais pas garantir que cela fonctionnera mieux, mais c'est ma façon habituelle de corréler une ligne avec une ligne "précédente":
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)
(Je pense que c'est vrai - il faudrait peut-être quelques exemples de données pour le valider).
En gros, l'idée est de joindre la table à elle-même, et pour chaque ligne (en d
), trouver les lignes candidates (dans d_prev
) pour la ligne "précédente". Ensuite, faites une autre jointure, pour essayer de trouver une ligne (dans d_inter
) qui existe entre la ligne courante (en d
) et la ligne candidate (dans d_prev
). Si nous ne trouvons pas une telle ligne (d_inter.time is null
), alors ce candidat était bien la ligne précédente.