2017-08-14 107 views
0

我有一些數據非常類似:拆分分隔成錶行

ID STATUS     EMPL 
1 Created;Solved;Closed John;Terry;Martin 

當然的每一行中值的數量可以從1到n。我發現這方面的一些建議1列只(使用CONNECT BY與REGEXP_SUBSTR)

有什麼辦法(SQL或PL/SQL明智),以得到所需的輸出:

ID STATUS EMPL 
1 Created John 
1 Solved Terry 
1 Closed Martin 

感謝

+0

寫一個函數或SP。有一個遊標在其中,並與每一行循環。在每一行中,如問題所示,用(;)分割數據。現在有一個臨時表並繼續添加。 – Prathyush

+0

這會在你的應用層更容易處理,例如Java的。數據庫不是清理數據的最佳位置。 –

+0

首先規範化或至少使用集合類型。使用CSV是一個非常糟糕的主意。 – lad2025

回答

0

不知道對大表的性能,但是這種選擇應該工作

select st.id, st.status, em.empl from (
    select distinct id, level as lvl, regexp_substr(status,'[^;]+',1,level) as status 
    from to_split connect by regexp_substr(status,'[^;]+',1,level) is not null 
) st 
join (
    select distinct id, level as lvl, regexp_substr(empl,'[^;]+',1,level) as empl 
    from to_split connect by regexp_substr(empl,'[^;]+',1,level) is not null 
) em 
on st.id = em.id and st.lvl = em.lvl 
order by id; 
2
with d (id, status, empl) as 
(
    select 1 ,'Created;Solved;Closed',     'John;Terry;Martin'   from dual union all 
    select 2 ,'Created2;Reviewed2;Solved2;Closed2', 'John2;Bell2;Terry2;Martin2' from dual 
) 
,cte(id, status, s, e, empl, s1, e1, rn) as 
(
    select 
    id, status, 1, case when instr(status, ';') > 0 then instr(status, ';') else length(status)+1 end, 
      empl, 1, case when instr(empl, ';') > 0 then instr(empl, ';') else length(empl)+1 end, 0 
    from d 
    union all 
    select 
    id, status, e+1, case when instr(status, ';' , e+1) > 0 then instr(status, ';', e+1) else length(status)+1 end, 
      empl, e1+1, case when instr(empl, ';' , e1+1) > 0 then instr(empl, ';', e1+1) else length(empl)+1 end, rn+1 
    from cte where e <= length(status) 
    -- assumption: equal number of delimiters (;) in status and empl column values 
) 
select id, substr(status, s, e - s) status, substr(empl, s1, e1 - s1) empl from cte 
order by id,rn 
; 

     ID STATUS        EMPL      
---------- ---------------------------------- -------------------------- 
     1 Created       John      
     1 Solved        Terry      
     1 Closed        Martin      
     2 Created2       John2      
     2 Reviewed2       Bell2      
     2 Solved2       Terry2      
     2 Closed2       Martin2