Svar på uppdaterad fråga
SELECT *
FROM (
SELECT *
,lag(val, 1, 0) OVER (PARTITION BY status ORDER BY id) last_val
,lag(status) OVER (PARTITION BY val ORDER BY id) last_status
FROM t1
) x
WHERE status = 1
AND (last_val <> val OR last_status = 0)
Hur?
Samma som tidigare, men denna gång kombinera två fönsterfunktioner. Att slå på en enhet kvalificerar sig om ..
1. den senaste enheten som slogs på var annan en.
2. eller samma enhet har stängts av av i sin sista post. Hörnfallet med NULL
för den första raden i partitionen är irrelevant, eftersom raden då redan kvalificerade sig i 1.
Svar på originalversionen av frågan.
Om din Jag förstår din uppgift rätt, gör denna enkla fråga jobbet:
SELECT *
FROM (
SELECT *
,lag(val, 1, 0) OVER (ORDER BY id) last_on
FROM t1
WHERE status = 1
) x
WHERE last_on <> val
Returnerar raderna 1, 3, 6, 7 efter önskemål.
Hur?
Underfrågan ignorerar all avstängning, eftersom det bara är brus, enligt din beskrivning. Lämnar poster där en enhet är påslagen. Bland dessa är endast de poster diskvalificerade, där samma enhet redan var på (den senaste posten slås på). Använd fönsterfunktionen lag()
för det. Jag tillhandahåller särskilt 0
som standard för att täcka specialfallet för den första raden - förutsatt att det inte finns någon enhet med val = 0
.
Om det finns, välj ett annat omöjligt nummer.
Om inget nummer är omöjligt, lämna specialfallet som NULL
med lag(val) OVER ...
och i den yttre frågan kontrollera med:
WHERE last_on IS DISTINCT FROM val