Antwoord voor bijgewerkte vraag
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)
Hoe?
Hetzelfde als voorheen, maar deze keer twee vensterfuncties combineren. Het inschakelen van een apparaat komt in aanmerking als ..
1. het laatst ingeschakelde apparaat was een andere een.
2. of hetzelfde apparaat is uit uitgeschakeld in zijn laatste invoer. De hoekkast met NULL
voor de eerste rij van de partitie is niet relevant, omdat de rij dan al gekwalificeerd is in 1.
Antwoord voor originele versie van vraag.
Als ik uw taak goed begrijp, doet deze eenvoudige vraag het werk:
SELECT *
FROM (
SELECT *
,lag(val, 1, 0) OVER (ORDER BY id) last_on
FROM t1
WHERE status = 1
) x
WHERE last_on <> val
Retourneert rijen 1, 3, 6, 7 zoals gevraagd.
Hoe?
De subquery negeert alle uitschakelen, want dat is gewoon ruis, volgens uw beschrijving. Laat vermeldingen achter waar een apparaat is ingeschakeld. Daarvan worden alleen die inzendingen gediskwalificeerd, waarbij hetzelfde apparaat al was ingeschakeld (de laatste inzending wordt ingeschakeld). Gebruik de vensterfunctie lag()
daarom. In het bijzonder geef ik 0
standaard om het speciale geval van de eerste rij te dekken - ervan uitgaande dat er geen apparaat is met val = 0
.
Als dat zo is, kies dan een ander onmogelijk nummer.
Als geen nummer onmogelijk is, laat het speciale geval als NULL
met lag(val) OVER ...
en in de buitenste vraag controleer met:
WHERE last_on IS DISTINCT FROM val