Parece un problema de "brechas e islas":
WITH cte("hash","date") AS (
SELECT 'abcd', DATE'2017-11-01' FROM dual UNION ALL
SELECT 'abcd', DATE'2017-11-02' FROM dual UNION ALL
SELECT 'abcd', DATE'2017-11-03' FROM dual UNION ALL
SELECT 'wxyz', DATE'2017-11-04' FROM dual UNION ALL
SELECT 'wxyz', DATE'2017-11-05' FROM dual UNION ALL
SELECT 'abcd', DATE'2017-11-06' FROM dual UNION ALL
SELECT 'wxyz', DATE'2017-11-07' FROM dual UNION ALL
SELECT 'abcd', DATE'2017-11-08' FROM dual UNION ALL
SELECT 'abcd', DATE'2017-11-09' FROM dual UNION ALL
SELECT 'lmno', DATE'2017-11-10' FROM dual UNION ALL
SELECT 'lmno', DATE'2017-11-11' FROM dual
)
select "hash"
,min("date") as startdate
,max("date") as enddate
from (
select "date","hash"
, row_number() over (order by "date")
- row_number() over (partition by "hash" order by "date") as grp
from cte
) A
group by "hash", grp
ORDER BY startdate;