Réponse à la question mise à jour
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)
Comment ?
Comme avant, mais cette fois combinez deux fonctions de fenêtre. La mise en marche d'un appareil est admissible si ..
1. le dernier appareil allumé était un différent un.
2. ou le même appareil a été éteint dans sa dernière entrée. Le cas du coin avec NULL
pour la première ligne de la partition n'est pas pertinente, car alors la ligne est déjà qualifiée dans 1.
Réponse pour la version originale de la question.
Si vous avez bien compris votre tâche, cette simple requête fait l'affaire :
SELECT *
FROM (
SELECT *
,lag(val, 1, 0) OVER (ORDER BY id) last_on
FROM t1
WHERE status = 1
) x
WHERE last_on <> val
Renvoie les lignes 1, 3, 6, 7 comme demandé.
Comment ?
La sous-requête ignore toute mise hors tension, car ce n'est que du bruit, selon votre description. Laisse des entrées là où un appareil est allumé. Parmi ceux-ci, seules les entrées sont disqualifiées, où le même appareil était déjà allumé (la dernière entrée s'allumant). Utilisez la fonction de fenêtre lag()
pour ça. En particulier, je fournis 0
par défaut pour couvrir le cas particulier de la première ligne - en supposant qu'il n'y a pas de périphérique avec val = 0
.
S'il y en a un, choisissez un autre nombre impossible.
Si aucun nombre n'est impossible, laissez le cas particulier NULL
avec lag(val) OVER ...
et dans la requête externe, vérifiez avec :
WHERE last_on IS DISTINCT FROM val