Resposta para pergunta atualizada
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)
Como?
O mesmo que antes, mas desta vez combina duas funções de janela. Ligar um dispositivo se qualifica se ..
1. o último dispositivo ligado era um diferente um.
2. ou o mesmo dispositivo foi desligado em sua última entrada. A caixa de canto com
NULL
para a primeira linha da partição é irrelevante, pois a linha já está qualificada em 1. Resposta para a versão original da pergunta.
Se você entendeu sua tarefa corretamente, esta consulta simples faz o trabalho:
SELECT *
FROM (
SELECT *
,lag(val, 1, 0) OVER (ORDER BY id) last_on
FROM t1
WHERE status = 1
) x
WHERE last_on <> val
Retorna as linhas 1, 3, 6, 7 conforme solicitado.
Como?
A subconsulta ignora todos os desligamentos, pois isso é apenas ruído, de acordo com sua descrição. Deixa entradas onde um dispositivo está ligado. Destes, apenas são desqualificados os registos onde o mesmo dispositivo já estava ligado (a última entrada ligada). Use a função de janela
lag()
por isso. Em particular, forneço 0
como padrão para cobrir o caso especial da primeira linha - assumindo que não há dispositivo com val = 0
.Se houver, escolha outro número impossível.
Se nenhum número for impossível, deixe o caso especial como
NULL
com lag(val) OVER ...
e na consulta externa verifique com:WHERE last_on IS DISTINCT FROM val