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

ROW_NUMBER requête

create table test
(trip number
,stp  varchar2(1)
,tm   varchar2(10)
,seq  number);

insert into test values (1,     'A',     '1:10',   1);
insert into test values (1,     'B',     '1:16',   2); 
insert into test values (1,     'B',     '1:20',   2);
insert into test values (1 ,    'B',     '1:25',   2);
insert into test values (1 ,    'C',     '1:31',   3);
insert into test values (1,     'B',     '1:40',   4);
insert into test values (2,     'A',     '2:10',   1);
insert into test values (2,     'B',     '2:17',   2);
insert into test values (2,     'C',     '2:20',   3);
insert into test values (2,     'B',     '2:25',   4);

select t1.*
      ,sum(decode(t1.stp,t1.prev_stp,0,1)) over (partition by trip order by tm) new_seq
from  
     (select t.*
            ,lag(stp) over (order by t.tm) prev_stp
      from   test t
      order  by tm) t1
;

  TRIP S TM                SEQ P    NEW_SEQ
------ - ---------- ---------- - ----------
     1 A 1:10                1            1
     1 B 1:16                2 A          2
     1 B 1:20                2 B          2
     1 B 1:25                2 B          2
     1 C 1:31                3 B          3
     1 B 1:40                4 C          4
     2 A 2:10                1 B          1
     2 B 2:17                2 A          2
     2 C 2:20                3 B          3
     2 B 2:25                4 C          4

 10 rows selected 

Vous voulez voir si l'arrêt change d'une ligne à l'autre. Si c'est le cas, vous souhaitez incrémenter la séquence. Utilisez donc le décalage pour obtenir l'arrêt précédent dans la ligne actuelle.

J'ai utilisé DECODE en raison de la façon dont il gère les NULL et il est plus concis que CASE, mais si vous suivez le manuel, vous devriez probablement utiliser CASE.

L'utilisation de SUM comme fonction analytique avec une clause ORDER BY donnera la réponse que vous recherchez.