Możesz spróbować tego — nie gwarantuję, że będzie działać lepiej, ale to mój zwykły sposób skorelowania wiersza z „poprzednim” wierszem:
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)
(Myślę, że to prawda - przydałoby się trochę przykładowych danych, aby to sprawdzić).
Zasadniczo chodzi o dołączenie tabeli do siebie i dla każdego wiersza (w d
), znajdź wiersze kandydatów (w d_prev
) dla „poprzedniego” wiersza. Następnie wykonaj kolejne sprzężenie, aby spróbować znaleźć wiersz (w d_inter
), który istnieje między bieżącym wierszem (w d
) i wiersz kandydata (w d_prev
). Jeśli nie możemy znaleźć takiego wiersza (d_inter.time is null
), to kandydat rzeczywiście był w poprzednim rzędzie.