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/