2016-07-28 51 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

是的,我可以通过列扩展而不是行 –