Buscar usuarios que trabajaron durante 5 días consecutivos con range de dates en salida

Tengo una tabla tiene datos similares a los siguientes

Emp Date Code --- -------- ---- E1 11/1/2012 W E1 11/1/2012 V E2 11/1/2012 W E1 11/2/2012 W E1 11/3/2012 W E1 11/4/2012 W E1 11/5/2012 W 

Quiero get una list de empleados entre un range de dates (por ejemplo, para los últimos 3 meses) que trabajaron para el código W de forma condicional durante 5 días con el range de dates en la salida. Cada empleado puede tener múltiples loggings para un solo día con diferentes códigos.

El resultado esperado es

 Emp Date-Range --- ---------- E1 11/1 -11/5 

Debajo está lo que probé, pero no me acerqué en absoluto a la salida que busco

  SELECT distinct user, MIN(date) startdate, MAX(date) enddate FROM (SELECT user, date, (TRUNC(date) - ROWNUM) tmpcol FROM (SELECT user, date FROM tablename where date between to_date('10/01/2012','mm/dd/yyyy') and to_date('10/03/2012','mm/dd/yyyy') ORDER BY user, date) ot) t GROUP BY user, tmpcol ORDER BY user, startdate; 

Si Emp E1 ha funcionado durante 10 días consecutivos, debe aparecer dos veces en la salida con ambos intervalos de dates. Si E1 ha trabajado durante 9 días consecutivos (11/1 a 11/9), debe aparecer solo una vez con el intervalo de dates 11/1 a 11/9.

Ya he visto preguntas que son similares pero ninguna de ellas funcionó exactamente para mí. Mi database es Oracle 10G y no PL / SQL.

No estoy seguro de haber entendido todo correctamente, pero algo así podría ayudarte a empezar:

 select emp, sum(diff) as days, to_char(min(workdate), 'yyyy-mm-dd') as work_start, to_char(max(workdate), 'yyyy-mm-dd') as work_end from ( select * from ( select emp, workdate, code, nvl(workdate - lag(workdate) over (partition by emp, code order by workdate),1) as diff from tablename where code = 'W' and workdate between ... ) t1 where diff = 1 -- only consecutive rows ) t2 group by emp having sum(diff) = 5 

SQLFiddle: http://sqlfiddle.com/#!4/ad7ae/3

Tenga en count que workdate la date workdate lugar de la date ya que es una mala idea usar una palabra reservada como nombre de columna.

Puede comenzar desde aquí:

 select emp, count(*) over (partition by emp, code order by date_worked range interval '5' day preceding) as days_worked_last_5_days from table where code='W'; 

esas filas con days_worked_last_5_days = 5 son lo que buscas.

Mira este violín.

 Select emp, data-5, data from (SELECT EMP, DATA, WORK,lag, lead, row_number() over(PARTITION BY emp--, DATA ORDER BY DATA asc) rn FROM (SELECT emp, data, work, LAG (data) OVER (PARTITION BY emp ORDER BY data ASC) LAG, LEAD (data) OVER (PARTITION BY emp ORDER BY data ASC) LEAD FROM (SELECT emp, data, work, ROW_NUMBER () OVER (PARTITION BY emp, data ORDER BY data ASC) rn FROM example) WHERE rn = 1) a WHERE a.data + 1 = LEAD AND a.data - 1 = LAG ) WHERE rn = 5 

Donde el ejemplo de la tabla es:

EMP (varchar2), date, 'W' o 'F'

 SELECT * FROM ( SELECT USERID,USEDATE,WRK,RANK() OVER (PARTITION BY USERID,WRK ORDER BY USEDATE ) AS RNK1 FROM USER1 )U1 JOIN ( SELECT USERID,USEDATE,WRK,RANK() OVER (PARTITION BY USERID,WRK ORDER BY USEDATE ) AS RNK2 FROM USER1 )U2 ON U1.USERID=U2.USERID AND U1.RNK1+3=U2.RNK2 AND U2.USEDATE-U1.USEDATE=3;