PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Rileva l'isola SQL su più parametri e condizioni

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