PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Detecte a ilha SQL em vários parâmetros e condições

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