Quatro anos se passaram desde que essa pergunta foi feita. Mas a Oracle adicionou o MATCH_RECOGNIZE cláusula para Oracle 12c, e isso tornou a solução mais simples.
SELECT
foo_id, high_speed, speed,
NVL(DateFromZ, DateFrom) DateFrom,
NVL(DateToZ, DateTo) DateTo
FROM test
MATCH_RECOGNIZE (
ORDER BY RecordId
MEASURES
FIRST(zeros.DateFrom) AS DateFromZ,
FINAL LAST(zeros.DateTo) AS DateToZ,
COUNT(*) AS cnt
ALL ROWS PER MATCH WITH UNMATCHED ROWS
PATTERN (zeros+)
DEFINE
zeros AS zeros.speed = 0
)
WHERE speed > 0 OR cnt = 1
ORDER BY RecordId;
Resultado:
+--------+------------+-------+------------+------------+
| FOO_ID | HIGH_SPEED | SPEED | DATEFROM | DATETO |
+--------+------------+-------+------------+------------+
| 12 | 60 | 10 | 09/11/2011 | 10/11/2011 |
| 13 | 20 | 20 | 11/11/2011 | 11/11/2011 |
| 12 | 0 | 0 | 13/11/2011 | 14/11/2011 |
| 12 | 70 | 50 | 15/11/2011 | 26/11/2011 |
| 12 | 40 | 40 | 09/11/2011 | 09/11/2011 |
| 13 | 25 | 20 | 09/11/2011 | 09/11/2011 |
| 12 | 0 | 0 | 15/11/2011 | 19/11/2011 |
| 12 | 20 | 10 | 12/11/2011 | 12/11/2011 |
+--------+------------+-------+------------+------------+
Demonstração em db<>fiddle .