Я бы так и сделал.
Идея состоит в том, чтобы каждая строка получала максимальное значение всех строк, следующих после, и минимальное значение всех строк, следующих после.Если значение совпадает с минимальным и максимальным, вы их подсчитываете.
SELECT ID, COUNT(*) FROM (
SELECT
ID,
VALUE,
MIN(VALUE) OVER ( PARTITION BY ID ORDER BY D ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) AS MIN_NEXT,
MAX(VALUE) OVER ( PARTITION BY ID ORDER BY D ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) AS MAX_NEXT
FROM T
) WHERE VALUE=MIN_NEXT AND VALUE=MAX_NEXT
GROUP BY ID;
Для теста: http://sqlfiddle.com/#!4/046b1/1