ROW_NUMBER 查询

ROW_NUMBER query

我有一个 table:

Trip  Stop  Time 
-----------------
1     A     1:10
1     B     1:16
1     B     1:20
1     B     1:25
1     C     1:31
1     B     1:40
2     A     2:10
2     B     2:17
2     C     2:20
2     B     2:25  

我想在我的查询输出中再添加一列:

Trip  Stop  Time Sequence
-------------------------
1     A     1:10   1
1     B     1:16   2 
1     B     1:20   2
1     B     1:25   2
1     C     1:31   3
1     B     1:40   4 
2     A     2:10   1
2     B     2:17   2
2     C     2:20   3
2     B     2:25   4  

困难的部分是B,如果B彼此相邻我希望它是相同的序列,如果不是则算作一个新行。

我知道

row_number over (partition by trip order by time)
row_number over (partition by trip, stop order by time)

None个都会满足我要的条件。有没有办法查询这个?

select *, dense_rank() over(partition by trip, stop order by time) as sqnc
from yourtable;

使用 dense_rank 这样您就可以连续获取所有数字,中间没有跳过的数字。

我认为这比简单的 row_number() 更复杂。您需要确定相邻停靠点组,然后然后枚举它们。

您可以使用不同的行号来识别组。然后,如果行程中没有重复停靠点,差值上的 dense_rank() 会执行您想要的操作:

select t.*,
       dense_rank() over (partition by trip order by grp, stop)
from (select t.*,
             (row_number() over (partition by trip order by time) -
              row_number() over (partition by trip, stop order by time)
             ) as grp
      from table t
     ) t;

如果有:

select t.*, dense_rank() over (partition by trip order by mintime)
from (select t.*,
             min(time) over (partition by trip, grp, stop) as mintime
      from (select t.*,
                   (row_number() over (partition by trip order by time) -
                    row_number() over (partition by trip, stop order by time)
                   ) as grp
            from table t
           ) t
     ) t;
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 

您想查看停靠点是否在一行和下一行之间发生变化。如果是这样,您想增加序列。因此,使用滞后将上一个停止点放入当前行。

我使用 DECODE 是因为它处理 NULL 的方式比 CASE 更简洁,但如果您按照教科书学习,您可能应该使用 CASE。

将 SUM 用作带有 ORDER BY 子句的分析函数将给出您正在寻找的答案。