Я думаю, что это лучше всего решить, используя функции Windows и отфильтрованный агрегат.
Для каждой строки добавьте число более поздних строк, имеющих state = 'OFF'
, а затем используйте только те строки, для которых это число равно 0.
Вам нужен подзапрос, потому что вы не можете использовать результат оконной функции в условии WHERE
(WHERE
оценивается перед оконными функциями).
SELECT id, state, date
FROM (SELECT id, state, date,
count(*) FILTER (WHERE state = 'OFF')
OVER (ORDER BY date DESC, state DESC) AS later_off_count
FROM tab) q
WHERE later_off_count = 0;
id | state | date
----+-------+------------
10 | ON | 2018-02-23
9 | ON | 2018-02-22
8 | ON | 2018-02-22
7 | ON | 2018-02-22
(4 rows)