Oracle
 sql >> Base de données >  >> RDS >> Oracle

Fonctions Oracle Analytic - réinitialisation d'une clause de fenêtrage

C'est un peu compliqué. Au lieu d'utiliser rank() ou similaire, utilisez lag() pour voir quand quelque chose change. Ensuite, faites une somme cumulée du drapeau.

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;

Voici le SQLFiddle.

MODIFIER :

C'est Gordon qui édite ma propre réponse. Oups. La requête d'origine était à 90 % du chemin. Il a identifié les groupes où les nombres devraient augmenter, mais n'a pas attribué les numéros au sein des groupes. Je ferais cela avec un autre niveau de row_number() comme dans :

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;

Donc, l'idée générale est la suivante. Utilisez d'abord lag() pour déterminer où commence un groupe (c'est-à-dire où il y a un changement de service d'une date à l'autre). Ensuite, attribuez-leur un "identifiant de groupe", en faisant une somme cumulée. Ce sont les enregistrements qui doivent être énumérés. La dernière étape consiste à les énumérer à l'aide de row_number() .