Oracle
 sql >> Database >  >> RDS >> Oracle

Funzioni di Oracle Analytic:reimpostazione di una clausola di windowing

Questo è un po' complicato. Invece di usare rank() o simili, usa lag() per vedere quando qualcosa cambia. Quindi fai una somma cumulativa del flag.

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;

Ecco SQLFiddle.

MODIFICA:

Questo è Gordon che modifica la mia risposta. Ops. La query originale era al 90% del percorso. Ha identificato i gruppi dove i numeri dovrebbero aumentare, ma non ha assegnato i numeri all'interno dei gruppi. Lo farei con un altro livello di row_number() come in:

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;

Quindi, l'idea generale è la seguente. Per prima cosa usa lag() per determinare dove inizia un gruppo (ovvero, dove c'è un cambio di reparto da una data all'altra). Quindi, assegna un "ID gruppo" a questi, facendo una somma cumulativa. Questi sono i record che devono essere enumerati. Il passaggio finale è enumerarli usando row_number() .