Oracle:枚举类似行的组

时间:2010-09-10 10:31:24

标签: sql oracle

我有下表:

ID  |  X  
1   |  1  
2   |  2  
3   |  5  
4   |  6
5   |  7
6   |  9  

我需要枚举行组,如果行 i i-1 在X列中的差异小于2,则它们应该具有相同的组号N.见下面的例子。

ID  |  X  | N
1   |  1  | 1
2   |  2  | 1
3   |  5  | 2
4   |  6  | 2
5   |  7  | 2
6   |  9  | 3

请注意,行X(2)-X(1)= 1,因此它们在第一组中分组。比X(3)-X(2)= 3所以第3行进入第3和第4行的第2组。 X(6)-X(5)= 2所以第6行在第3组中。

任何人都可以帮我编写将返回第二个表的SQL查询吗?

3 个答案:

答案 0 :(得分:3)

这应该这样做:

select id, x, sum(new_group) over (order by id) as group_no
from
( select id, x, case when x-prev_x = 1 then 0 else 1 end new_group
  from
  ( select id, x, lag(x) over (order by id) prev_x
    from mytable
  )
);

我通过该查询获得了正确的数据答案。

答案 1 :(得分:3)

SQL> create table mytable (id,x)
  2  as
  3  select 1, 1 from dual union all
  4  select 2, 2 from dual union all
  5  select 3, 5 from dual union all
  6  select 4, 6 from dual union all
  7  select 5, 7 from dual union all
  8  select 6, 9 from dual
  9  /

Table created.

SQL> select id
  2       , x
  3       , sum(y) over (order by id) n
  4    from ( select id
  5                , x
  6                , case x - lag(x) over (order by id)
  7                  when 1 then 0
  8                  else 1
  9                  end y
 10             from mytable
 11         )
 12   order by id
 13  /

        ID          X          N
---------- ---------- ----------
         1          1          1
         2          2          1
         3          5          2
         4          6          2
         5          7          2
         6          9          3

6 rows selected.

这与Tony的回答基本相同,只有一个内联视图更少。

此致 罗布。

答案 2 :(得分:0)

仅使用基本操作:

create table test(id int, x int);
insert into test values(1, 1), (2, 2), (3, 5), (4, 6), (5, 7), (6, 9);

create table temp as 
select rownum() r, 0 min, x max 
from test t 
where not exists(select * from test t2 where t2.x = t.x + 1);

update temp t set min = select max + 1 from temp t2 where t2.r = t.r - 1;
update temp t set min = 0 where min is null;

select * from temp order by r;

select t.id, t.x, x.r from test t, temp x where t.x between x.min and x.max;

drop table test;
drop table temp;