Oracle使用存储过程实现多行对同行数据排列组合

Oracle使用存储过程实现同行数据排列组合

对多行的同一行的多列数据进行排列组合

假设获取的原来的数据如下表

A B C D
aa ab ac ad

现在我们需要对数据进行处理,将每一行的数据,类似于aa,ab,ac,ad,对这些列的值进行排列组合,输出类似于下面的结果

main main_1
aa ab
aa ac
aa ad
ab ac
ab ad
ac ad

不多BB,存储过程实现部分

create or replace procedure XXXXXXXXXX(WWW Integer) as
  MAIN      Varchar2(50);
  ALT       Varchar2(50);
  cursor CAI is
select l.a, l.b, l.c, l.d, l.keyid, l.S
  from UPL l, CO o
 where o.O = l.S
   and o.W = WWW;
begin
  --展开游标,取每一行的数据
  for AI in CAI loop
    --判断条件:当一行存在一个以上的时候,才执行下面的操作 
    if AI.a is not null and
       (AI.b is not null or AI.c is not null or AI.d is not null) then
      --列转行并进行排列组合
      for AA in (select sys_connect_by_path(it.IV, '#') CC
                   from (select *
                           from (select *
                                   from (select l.a,
                                                l.b,
                                                l.c,
                                                l.d,
                                                l.keyid,
                                                l.S
                                           from UPL l, CO o
                                          where o.O = l.S
                                            and o.W = WWW) t unpivot(IV for verder_v in(a as 'a',
                                                                                        b as 'b',
                                                                                        c as 'c',
                                                                                        d as 'd'))) tt
                          where tt.k = AI.k
                            and tt.S = AI.S
                          order by tt.k asc) it
                  where level = 2
                 connect by prior verder_v < it.verder_v
                        and level <= 2) loop
        --拆分成两部分
        select substr(substr(AA.CC, 2, length(AA.CC)),
                      0,
                      instr(substr(AA.CC, 2, length(AA.CC)), '#') - 1),
               substr(substr(AA.CC, 2, length(AA.CC)),
                      instr(substr(AA.CC, 2, length(AA.CC)), '#') + 1,
                      length(AA.CC))
          into MAIN, ALT
          from dual;
        dbms_output.put_line(MAIN || ' 。' || ALT);
        ---然后将结果插入存储表中即可
      end loop;
    end if;
  end loop;
end;

PS:如果不需要行转列的话,就可以用下面的,比较直观

select sys_connect_by_path(it.itemcode_v, '#') combo
                            from (select *
                                    from (select rownum seq,t.itemcode from ttt20231025 t) tt
                                   order by tt.seq asc) it
                           where level = 2
                          connect by prior seq < it.seq
                                 and level <= 2

其中ttt20231025的数据为
image

执行后结果为
image

以上

posted @ 2022-11-11 16:44  DbWong_0918  阅读(86)  评论(0编辑  收藏  举报