Plsql 带扭曲的转置表:聚合同一行上的类似字段

Plsql 带扭曲的转置表:聚合同一行上的类似字段,plsql,oracle11g,oracle-sqldeveloper,Plsql,Oracle11g,Oracle Sqldeveloper,我整个上午都在寻找以下问题的答案(如果这是转载,请原谅,但我真的为这个问题发疯了) 我有客户AAA、BBB、CCC、DDD和个人XXX、YYY、ZZZ relation_id client in_relation_with relation_type --- --- --- --- 1 AAA XXX R1 2 AAA YYY

我整个上午都在寻找以下问题的答案(如果这是转载,请原谅,但我真的为这个问题发疯了)

我有客户
AAA、BBB、CCC、DDD
和个人
XXX、YYY、ZZZ

relation_id   client  in_relation_with  relation_type
---           ---     ---               ---
1             AAA     XXX               R1
2             AAA     YYY               R1
3             AAA     ZZZ               R3
4             BBB     XXX               R2
5             BBB     YYY               R5
6             CCC     XXX               R2
7             DDD     ZZZ               R4
8             DDD     YYY               R4
9             DDD     XXX               R4
我想要下表:

client  R1.1      R1.2      R2       R3       R4.1     R4.2    R4.3    R5
---     ---       ---       ---      ---      ---      ---     ---     ---
AAA     XXX       YYY       -        ZZZ      -        -       -       -
BBB     -         -         XXX      -        -        -       -       YYY
CCC     -         -         XXX      -        -        -       -       -
DDD     -         -         -        -        XXX      YYY     ZZZ     -
问题在于,客户(
DDD
)可能与不同的人(
XXX,YYY,ZZZ
)有类似的关系(类型
R4
),与我们的客户有关系的人的数量是先验未知的,但可以通过
关系
表上的
max
语句找到。 最难的部分是这些
R1.1、R1.2、R4.1…
列和
null
,其中不存在任何关系(至少对我而言)

在PL/SQL中实现这一点有可能吗

非常感谢

干杯


G

我可以想到类似下面的解决方案,可以将其更改为解析delimeter分隔值,将其转换为列

with relations as (select 1 relation_id, 'AAA' client, 'XXX' in_relation_with, 'R1' relation_type
                      from dual
                    union all
                    select 2, 'AAA', 'YYY', 'R1'
                      from dual
                    union all
                    select 3, 'AAA', 'ZZZ', 'R3'
                      from dual
                    union all
                    select 4, 'BBB', 'XXX', 'R2'
                      from dual
                    union all
                    select 5, 'BBB', 'YYY', 'R5'
                      from dual
                    union all
                    select 6, 'CCC', 'XXX', 'R2'
                      from dual
                    union all
                    select 7, 'DDD', 'ZZZ', 'R4'
                      from dual
                    union all
                    select 8, 'DDD', 'YYY', 'R4'
                      from dual
                    union all
                    select 9, 'DDD', 'XXX', 'R4'
                      from dual
                    )
select *       
  from relations
pivot
(
listagg(in_relation_with, ',') within group(order by relation_id)
for relation_type in ('R1' as r1, 'R2' as r2, 'R3' as r3, 'R4' as r4, 'R5' as r5)
)
希望这能对您有所帮助。

这是代码。请参见小提琴

select 
  client,
  case when instr(r1, ',')>=1 then regexp_substr(r1,'[^,]+',1,1) else r1   end r1_1,
  case when instr(r1, ',')>=1 then regexp_substr(r1,'[^,]+',1,2) else null end r1_2,
  r2,
  r3,
  case when instr(r4, ',')>=1 then regexp_substr(r4,'[^,]+',1,1) else r1   end r1_1,
  case when instr(r4, ',')>=1 then regexp_substr(r4,'[^,]+',1,2) else null end r4_2,
  case when instr(r4, ',')>=1 then regexp_substr(r4,'[^,]+',1,3) else null end r4_3,
  r5
  from( 
    with relations as (
      select 1 relation_id, 'AAA' client, 'XXX' in_relation_with, 'R1' relation_type from dual union all
      select 2            , 'AAA'       , 'YYY'                 , 'R1'               from dual union all
      select 3            , 'AAA'       , 'ZZZ'                 , 'R3'               from dual union all
      select 4            , 'BBB'       , 'XXX'                 , 'R2'               from dual union all
      select 5            , 'BBB'       , 'YYY'                 , 'R5'               from dual union all
      select 6            , 'CCC'       , 'XXX'                 , 'R2'               from dual union all
      select 7            , 'DDD'       , 'ZZZ'                 , 'R4'               from dual union all
      select 8            , 'DDD'       , 'YYY'                 , 'R4'               from dual union all
      select 9            , 'DDD'       , 'XXX'                 , 'R4'               from dual
    )
      select *       
        from relations
        pivot(
          listagg(in_relation_with, ',') 
          within group(order by relation_id)
          for relation_type in ('R1' as r1, 'R2' as r2, 'R3' as r3, 'R4' as r4, 'R5' as r5)
        )
  );

可能在以下位置发现了一些东西:是的,确实有帮助,尽管正如您所提到的,问题是将这些伪列转换为真实列。。但至少现在它是好的:)与这里可以找到的东西结合在一起:\o/