sql >> Base de Datos >  >> RDS >> PostgreSQL

Detecte la isla SQL sobre múltiples parámetros y condiciones

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