Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Funções do Oracle Analytic - redefinindo uma cláusula de janela


Isso é um pouco complicado. Em vez de usar rank() ou algo parecido, use lag() para ver quando algo muda. Em seguida, faça uma soma cumulativa do sinalizador.
select dept, date1,
       CASE WHEN StartFlag = 0 THEN 1
            ELSE 1+StartFlag+NVL(lag(StartFlag) over (order by date1),0)
       END as rnk
from (select t1.*,
             (case when dept = lag(dept) over (order by date1)
                   then 1
                   else 0
              end) as StartFlag
      from t1
     ) t1
order by date1;

Aqui está o SQLFiddle.

EDITAR:

Este é Gordon editando minha própria resposta. Ops. A consulta original foi de 90% do caminho até lá. Identificou os grupos onde os números deveriam aumentar, mas não atribuímos os números dentro dos grupos. Eu faria isso com outro nível de row_number() como em:
select dept, date1,
       row_number() over (partition by dept, grp order by date1) as rnk
from (select dept, date1, startflag,
             sum(StartFlag) over (partition by dept order by date1) as grp
      from (select t1.*,
                   (case when dept = lag(dept) over (order by date1)
                         then 0
                         else 1
                    end) as StartFlag
            from t1
           ) t1
     ) t1
order by date1;

Então, a ideia geral é a seguinte. Primeiro use lag() para determinar onde um grupo começa (ou seja, onde há uma mudança de departamento de uma data para outra). Em seguida, atribua um "id de grupo" a eles, fazendo uma soma cumulativa. Esses são os registros que devem ser enumerados. A etapa final é enumerá-los usando row_number() .