Risposta alla domanda aggiornata
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)
Come?
Come prima, ma questa volta combina due funzioni della finestra. L'accensione di un dispositivo si qualifica se ..
1. l'ultimo dispositivo acceso era un diverso uno.
2. oppure lo stesso dispositivo è stato spento nella sua ultima voce. Il caso d'angolo con NULL
per la prima riga della partizione è irrilevante, perché allora la riga già qualificata in 1.
Risposta per la versione originale della domanda.
Se il tuo ho capito correttamente il tuo compito, questa semplice query fa il lavoro:
SELECT *
FROM (
SELECT *
,lag(val, 1, 0) OVER (ORDER BY id) last_on
FROM t1
WHERE status = 1
) x
WHERE last_on <> val
Restituisce le righe 1, 3, 6, 7 come richiesto.
Come?
La sottoquery ignora tutti gli spegnimenti, poiché si tratta solo di rumore, secondo la tua descrizione. Lascia le voci in cui un dispositivo è acceso. Tra queste sono squalificate solo le voci in cui lo stesso dispositivo era già acceso (l'ultima voce si è accesa). Usa la funzione finestra lag()
per quello. In particolare fornisco 0
come impostazione predefinita per coprire il caso speciale della prima riga, supponendo che non ci sia alcun dispositivo con val = 0
.
Se esiste, scegli un altro numero impossibile.
Se nessun numero è impossibile, lascia il caso speciale come NULL
con lag(val) OVER ...
e nella query esterna controlla con:
WHERE last_on IS DISTINCT FROM val