Antwort auf aktualisierte Frage
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)
Wie?
Wie zuvor, aber dieses Mal zwei Fensterfunktionen kombinieren. Das Einschalten eines Geräts qualifiziert sich, wenn ..
1. das zuletzt eingeschaltete Gerät war ein anderes eins.
2. oder dasselbe Gerät wurde ausgeschaltet in seinem letzten Eintrag. Der Eckfall mit NULL
für die erste Zeile der Partition ist irrelevant, weil dann die Zeile bereits in 1. qualifiziert ist
Antwort für Originalversion der Frage.
Wenn Sie Ihre Aufgabe richtig verstehen, reicht diese einfache Abfrage:
SELECT *
FROM (
SELECT *
,lag(val, 1, 0) OVER (ORDER BY id) last_on
FROM t1
WHERE status = 1
) x
WHERE last_on <> val
Gibt wie angefordert die Zeilen 1, 3, 6, 7 zurück.
Wie?
Die Unterabfrage ignoriert alle Abschaltungen, da dies nach Ihrer Beschreibung nur Rauschen ist. Hinterlässt Einträge, wo ein Gerät eingeschaltet ist. Darunter werden nur diejenigen Einträge disqualifiziert, bei denen das gleiche Gerät bereits eingeschaltet war (der letzte Eintrag schaltete ein). Verwenden Sie die Fensterfunktion lag()
dafür. Insbesondere gebe ich 0
an als Standard, um den Sonderfall der ersten Zeile abzudecken - vorausgesetzt, es gibt kein Gerät mit val = 0
.
Wenn ja, wählen Sie eine andere unmögliche Zahl.
Wenn keine Zahl unmöglich ist, belassen Sie den Sonderfall bei NULL
mit lag(val) OVER ...
und in der äußeren Abfrage prüfen mit:
WHERE last_on IS DISTINCT FROM val