繁体   English   中英

ROW_NUMBER查询

[英]ROW_NUMBER query

我有一张桌子:

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)

他们都不会满足我想要的条件。 有没有办法查询这个?

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

使用dense_rank可以连续获得所有数字,中间没有跳过的数字。

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 

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

我使用DECODE是因为它处理NULL的方式,它比CASE更简洁,但是如果你关注教科书,你应该使用CASE。

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

我认为这比简单的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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM