0

我正在尝试基于一组 item_ids 创建 group_ids。item_ids 是单个组的一部分的唯一迹象是 item_ids 是连续的。例如,基于下面的前两列,我想要的输出是第三列:

item  item_id   group_id
ABC   282       2
ABC   283       2
ABC   284       2
ABC   285       2
ABC   051       3
ABC   052       3
ABC   189       4
ABC   231       5
ABC   232       5
ABC   233       5
ABC   234       5
ABC   247       6
ABC   248       6
ABC   249       6
ABC   250       6
ABC   091       7
ABC   092       7

group_id 本身不一定是顺序的,它只需要是唯一的。我尝试使用以下代码:

create sequence seq
   start with 1
   minvalue 1
   increment by 1
   cache 20;

select seq.nextval from dual; --to initialize the sequence

select 
   item,
   item_id,
   case when diff = 1 then seq.currval else seq.nextval end group_id
from
   (
       select
           item,
           item_id,
           (id - lag(id, 1, 0) over (order by 1) diff
       from
           (
               select
                   item,
                   item_id
               from
                   table
            )
    );

但得到以下输出:

item  item_id   group_id
ABC   282       2
ABC   283       3
ABC   284       4
ABC   285       5
ABC   051       6
ABC   052       7
ABC   189       8
ABC   231       9
ABC   232       10
ABC   233       11
ABC   234       12
ABC   247       13
ABC   248       14
ABC   249       15
ABC   250       16
ABC   091       17
ABC   092       18

在寻找问题的原因时,我发现用户 ShannonSeverance 的一个很好的解释详细说明了为什么我的解决方案不起作用。但是,它没有就如何前进提供任何建议。

有没有人有任何想法?

4

1 回答 1

1

你有一个问题,因为 SQL 表本质上是无序的。以下“应该”在逻辑上有效,但在实践中不会:

select ii.*, (item_id - rownum) as grp_id
from item_ids ii;

按顺序减去行号的 item_id 序列是恒定的。您可以将其用于组,至少用于给定项目。要处理多个项目,请将值连接在一起:

select ii.*, item||'-'||(item_id - rownum) as grp_id
from item_ids ii;

要真正完成这项工作,您需要添加一个order by-- 这保证了select. 假设组之间存在“漏洞”,这可能会起作用:

select ii.*, item||'-'||(item_id - rownum) as grp_id
from item_ids ii
order by item, item_id;

否则,您需要一些其他列来确定项目的正确排序。

于 2013-08-30T01:28:43.363 回答