Respuesta a la pregunta actualizada
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)
¿Cómo?
Igual que antes, pero esta vez combina dos funciones de ventana. Encender un dispositivo califica si ..
1. el último dispositivo encendido era un diferente uno.
2. o el mismo dispositivo ha sido apagado en su última entrada. El caso de la esquina con NULL
para la primera fila de la partición es irrelevante, porque entonces la fila ya califica en 1.
Respuesta a la versión original de la pregunta.
Si entiendo su tarea correctamente, esta simple consulta hace el trabajo:
SELECT *
FROM (
SELECT *
,lag(val, 1, 0) OVER (ORDER BY id) last_on
FROM t1
WHERE status = 1
) x
WHERE last_on <> val
Devuelve las filas 1, 3, 6, 7 según lo solicitado.
¿Cómo?
La subconsulta ignora todos los apagados, ya que eso es solo ruido, según su descripción. Deja entradas donde un dispositivo está encendido. Entre ellos, solo se descalifican aquellas entradas en las que el mismo dispositivo ya estaba encendido (la última entrada se encendió). Use la función de ventana lag()
para eso. En particular, proporciono 0
por defecto para cubrir el caso especial de la primera fila, asumiendo que no hay ningún dispositivo con val = 0
.
Si lo hay, elija otro número imposible.
Si ningún número es imposible, deje el caso especial como NULL
con lag(val) OVER ...
y en la consulta externa verifique con:
WHERE last_on IS DISTINCT FROM val