Отговор за актуализиран въпрос
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)
Как?
Същото като преди, но този път комбинира две функции на прозореца. Включването на устройство отговаря на условията, ако ..
1. последното включено устройство беше различно едно.
2. или същото устройство е било изключено в последния си запис. Ъгловият случай с NULL
за първия ред на дяла е без значение, защото тогава редът вече е квалифициран в 1.
Отговор за оригиналната версия на въпроса.
Ако разбирам правилно задачата ви, тази проста заявка върши работата:
SELECT *
FROM (
SELECT *
,lag(val, 1, 0) OVER (ORDER BY id) last_on
FROM t1
WHERE status = 1
) x
WHERE last_on <> val
Връща редове 1, 3, 6, 7 според заявката.
Как?
Подзаявката игнорира всички изключвания, тъй като това е просто шум, според вашето описание. Оставя записи, когато устройството е включено. Сред тях само тези записи са дисквалифицирани, при които същото устройство вече е било включено (последното включване се включва). Използвайте прозоречната функция lag()
за това. По-специално предоставям 0
по подразбиране, за да покрие специалния случай на първия ред - ако приемем, че няма устройство с val = 0
.
Ако има, изберете друго невъзможно число.
Ако нито едно число не е невъзможно, оставете специалния случай като NULL
с lag(val) OVER ...
и във външната заявка проверете с:
WHERE last_on IS DISTINCT FROM val