将CSV列拆分为行并跨列匹配

时间:2017-03-19 14:43:29

标签: oracle

我有一张表格,其格式如下。

PK COL1          COl2 
r1 abc,abd       zyx,xyz 
r2 bde,cse,bxo   ajy,bix,rxo 
r3 zde,cse,bxo   ajy,xir,sxo

COL1中的条目序列映射到COL2,即在r1上,abc映射到zyx,abd映射到xyz。不要问我是谁提出这个想法:)

所以现在我需要将其转换为常规的关系结构。

PK COL1 COL2
r1 abc  zyx
r1 abd  xyz
r2 bde  ajy  
r2 cse  bix
r2 bxo  rxo
r3 zde  ajy  
r3 cse  xir
r3 bxo  sxo

我已经查看了可用于将CSV列转换为行的其他示例。所有这些都适用于单个CSV列。但是使用2个CSV列,a)如何使其工作; b)还确保映射序列不受干扰。有什么建议吗?

由于 askids

2 个答案:

答案 0 :(得分:1)

with
     test_data ( pk, col1, col2 ) as ( 
       select 'r1', 'abc,abd'    , 'zyx,xyz'     from dual union all 
       select 'r2', 'bde,cse,bxo', 'ajy,bix,rxo' from dual union all 
       select 'r3', 'zde,cse,bxo', 'ajy,xir,sxo' from dual
     )
-- end of test data, SQL query begins below this line
select pk, 
       regexp_substr(col1, '([^,]*)(,|$)', 1, level, null, 1) as col1,
       regexp_substr(col2, '([^,]*)(,|$)', 1, level, null, 1) as col2
from   test_data
connect by level <= length(col1) - length(replace(col1, ',')) + 1
       and prior pk = pk
       and prior sys_guid() is not null
;

PK  COL1  COL2
--  ----  ----
r1  abc   zyx
r1  abd   xyz
r2  bde   ajy
r2  cse   bix
r2  bxo   rxo
r3  zde   ajy
r3  cse   xir
r3  bxo   sxo

答案 1 :(得分:0)

请注意,如果col1或col2在逗号之间可能包含空值,则需要更复杂的正则表达式:

SQL> select
  t.pk,
  regexp_substr(t.col1, '[^,]+',1,ordno.n) as col1,
  regexp_substr(t.col2, '[^,]+',1,ordno.n) as col2
from (
  select 'r1' pk, 'abc,abd' col1, 'zyx,xyz' col2 from dual union all
  select 'r2' pk, 'bde,cse,bxo' col1, 'ajy,bix,rxo' col2 from dual union all
  select 'r3' pk, 'zde,cse,bxo' col1, 'ajy,xir,sxo' col2 from dual
  ) t
  join (select level n from dual connect by level <= 1000) ordno
    on ordno.n <= regexp_count(t.col1, '[^,]+')
order by t.pk;

PK COL1        COL2      
-- ----------- -----------
r1 abc         zyx        
r1 abd         xyz        
r2 cse         bix        
r2 bxo         rxo        
r2 bde         ajy        
r3 zde         ajy        
r3 bxo         sxo        
r3 cse         xir        

 8 rows selected