Du kanske provar det här - jag kommer inte att garantera att det kommer att fungera bättre, men det är mitt vanliga sätt att korrelera en rad med en "föregående" rad:
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)
(Jag tror att detta är rätt - skulle kunna göra med några exempeldata för att validera det).
I grund och botten är tanken att sammanfoga tabellen med sig själv och för varje rad (i d
), hitta kandidatrader (i d_prev
) för den "föregående" raden. Gör sedan ytterligare en koppling för att försöka hitta en rad (i d_inter
) som finns mellan den aktuella raden (i d
) och kandidatraden (i d_prev
). Om vi inte kan hitta en sådan rad (d_inter.time is null
), då var den kandidaten verkligen den föregående raden.