2016-07-28 48 views
1

比方說我的表看起來像這樣:拆分柱分成兩個或更多的甲骨文

------------------------- 
| id | prop    | 
------------------------- 
| 1 | Jhon_Dhoe_21  | 
------------------------- 
| 2 | Tom_Dohn_23_MALE | 
------------------------- 
| 3 | Scot    | 
------------------------- 

屬性將始終以「_」來devided。所以SELECT後的表應該是這樣的:

-------------------------------------- 
| id | prop1 | prop2 | prop3 | prop4 | 
-------------------------------------- 
| 1 | Jhon | Dhoe | 21 | NULL | 
-------------------------------------- 
| 2 | Tom | Dohn | 23 | MALE | 
-------------------------------------- 
| 3 | Scot | NULL | NULL | NULL | 
-------------------------------------- 

現在,如果我們知道性能(ñ)的最大數量,我們可以有,我想我們可以通過創建一個ň正則表達式expresions數支柱 列或其他東西。但如果我們不知道也許我們必須首先找到與大多數屬性?

編輯:

我不能接受多行。

+2

一個SQL查詢可以返回一組固定列。如果需要可變數量的列,則需要使用動態SQL或替代數據結構(例如嵌套表或JSON)。 –

+0

@GordonLinoff我明白了......謝謝Gordon我會研究關於SQL的動態使用情況,也許終於到了它的時候了。 –

+0

如果你可以爲每個'id'接受多行,那麼這是一個可能的解決方案:http://stackoverflow.com/questions/14328621/splitting-string-into-multiple-rows-in-oracle。 –

回答

2

這是一個有趣的問題,所以我已經解決了這種方式:

with 
    tbl as (
    select 1 id, 'Jhon_Dhoe_21' prop from dual union all 
    select 2 id, 'Tom_Dohn_23_MALE' prop from dual union all 
    select 3 id, 'Scot' prop from dual 
), 
    maxrows as (select level rn from dual connect by level <= 100) 
select id, regexp_substr(t.prop, '[^_]+', 1, mr.rn) prop_rn, rn, prop 
from tbl t, maxrows mr 
where mr.rn <= regexp_count(t.prop, '\_') + 1 
order by id, rn 

結果:

 ID PROP_RN     RN PROP 
---------- ---------------- ---------- ---------------- 
     1 Jhon      1 Jhon_Dhoe_21 
     1 Dhoe      2 Jhon_Dhoe_21 
     1 21      3 Jhon_Dhoe_21 
     2 Tom      1 Tom_Dohn_23_MALE 
     2 Dohn      2 Tom_Dohn_23_MALE 
     2 23      3 Tom_Dohn_23_MALE 
     2 MALE      4 Tom_Dohn_23_MALE 
     3 Scot      1 Scot 

8 rows selected 

如果你知道最大可能的列(或確認),你可以使用:

with 
    tbl as (
    select 1 id, 'Jhon_Dhoe_21' prop from dual union all 
    select 2 id, 'Tom_Dohn_23_MALE' prop from dual union all 
    select 3 id, 'Scot' prop from dual 
), 
    maxrows as (select level rn from dual connect by level <= 100), 
    tbl2 as (
    select id, regexp_substr(t.prop, '[^_]+', 1, mr.rn) prop_rn, rn, prop 
    from tbl t, maxrows mr 
    where mr.rn <= regexp_count(t.prop, '\_') + 1 
    order by id, rn) 
select * 
from tbl2 
pivot (
    max(prop_rn) 
    for rn in (1,2,3,4,6,7,8,9,10) 
) 

結果:

 ID PROP    1    2    3    4    6    7    8    9    10 
---------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- ---------------- 
     1 Jhon_Dhoe_21  Jhon    Dhoe    21                          
     3 Scot    Scot                                  
     2 Tom_Dohn_23_MALE Tom    Dohn    23    MALE                     

SQL> 

或者使用的XMLType:

with 
    tbl as (
    select 1 id, 'Jhon_Dhoe_21' prop from dual union all 
    select 2 id, 'Tom_Dohn_23_MALE' prop from dual union all 
    select 3 id, 'Scot' prop from dual 
), 
    maxrows as (select level rn from dual connect by level <= 100), 
    tbl2 as (
    select id, regexp_substr(t.prop, '[^_]+', 1, mr.rn) prop_rn, rn, prop 
    from tbl t, maxrows mr 
    where mr.rn <= regexp_count(t.prop, '\_') + 1 
    order by id, rn) 
select * 
from tbl2 
pivot xml (
    max(prop_rn) prp 
    for rn in (any) 
) 
+0

是的,這是一個可能的解決方案,但我不能接受多行,如果我當然可以工作。 –

+0

你只需要列?我問它,因爲使用動態SQL - 不是一個好方法...也許xmltype? – saphsys

+0

是的,我可以通過列擴展而不是行 –