一行数据当中有两个字段分别A和B  其中值存的内容是 A=32,25  B=12,13,14
actionid,action_note,a,b
119      火警        32,25   12,13,14变成
actionid,action_note,a,b
119      火警  32 12
119      火警  32 13
119      火警  32 14
119      火警  25 12
119      火警  25 13
119      火警  25 14

解决方案 »

  1.   


    --oracle 10g:with tab as (
    selecT '119' actionid, '火警' action_note, '32,25' a ,'12,13,14' b from dual
    )
    --上面是测试数据,下面是SQL:
    select distinct actionid,action_note,
           regexp_substr(a,'[^,]+',1,level) as a ,
           b
    from(
        select actionid,action_note,a,
              regexp_substr(b,'[^,]+',1,level) as b
        from tab
        connect by
        level<=length(b)-length(replace(b,',',''))+1
    )
    connect by
    level<=length(a)-length(replace(a,',',''))+1
    --result:
    ACTIONID ACTION_NOTE  A  B
    --------------------------------
    119 火警 25 12
    119 火警 25 13
    119 火警 25 14
    119 火警 32 12
    119 火警 32 13
    119 火警 32 14
      

  2.   

    说明一点,要是数据比较大的话,用上面的递归connect by 效率不敢保证,估计比较慢,而且还有去重distinct
      

  3.   

    第一步,建个拆分函数:CREATE OR REPLACE TYPE str_split IS TABLE OF VARCHAR2 (4000);
    CREATE OR REPLACE FUNCTION splitstr(p_string IN VARCHAR2, p_delimiter IN VARCHAR2)
        RETURN str_split 
        PIPELINED
    AS
        v_length   NUMBER := LENGTH(p_string);
        v_start    NUMBER := 1;
        v_index    NUMBER;
    BEGIN
        WHILE(v_start <= v_length)
        LOOP
            v_index := INSTR(p_string, p_delimiter, v_start);        IF v_index = 0
            THEN
                PIPE ROW(SUBSTR(p_string, v_start));
                v_start := v_length + 1;
            ELSE
                PIPE ROW(SUBSTR(p_string, v_start, v_index - v_start));
                v_start := v_index + 1;
            END IF;
        END LOOP;    RETURN;
    END splitstr;
    第二步,处理数据:select 119, '火警', a.*, b.*
      from table (select splitstr(a, ',') from tmp_jz where tid = 1) a,
           table (select splitstr(b, ',') from tmp_jz where tid = 1) b;
      

  4.   


    呵呵,是我不好意思,我本来想说的是 gelyon 他是牛人,用正则表达式,没别的意思
    点引用的时候点错了
      

  5.   

    ACTIONID ACTION_NOTE A B -------------------------------- 
    119 火警 25 12 
    119 火警 25 13 
    119 火警 25 14 
    119 火警 32 12 
    119 火警 32 13 
    119 火警 32 14 
    110 警察 32 14
    120 救护 32 12
      

  6.   

    第二步,处理数据:SQL code    select 119, '火警', a.*, b.* from table (select splitstr(a, ',') from tmp_jz where tid = 1) a, table (select splitstr(b, ',') from tmp_jz where tid = 1) b;这个 119,'火警' 还有其他内容
      

  7.   


    with tab as (
    selecT '119' actionid, '火警' action_note, '32,25' a ,'12,13,14' b from dual
    )select t1.actionid,t1.action_note,t2.a,t1.b from (select actionid,action_note,
              regexp_substr(b,'[^,]+',1,level) as b
        from tab
        connect by
        level<=length(b)-length(replace(b,',',''))+1) t1,
        (select actionid,
              regexp_substr(a,'[^,]+',1,level) as a
        from tab
        connect by
        level<=length(a)-length(replace(a,',',''))+1) t2 where t1.actionid=t2.actionid
    ACTIONID ACTION_NOTE A          B
    -------- ----------- ---------- ----------------
    119      火警        32         14
    119      火警        32         13
    119      火警        32         12
    119      火警        25         14
    119      火警        25         13
    119      火警        25         12
      

  8.   

    采用分布处理 72秒种处理一个字段
    create table  OSS_DICTION_TEST_channel as
    select distinct action_id,action_note,cate,thingid,
           regexp_substr(moduie_id,'[^,]+',1,level) as moduie_id,channel_id
    from 
    (
      select action_id,action_note,cate,thingid,moduie_id ,channel_id  
      from OSS_DICTION_TEST 
      where  channel_id like '%,%'
      or channel_id like '%,%'
      order by action_Id
    )
    connect by
    level<=length(moduie_id)-length(replace(moduie_id,',',''))+1select * from OSS_DICTION_TEST_channel
    create table  OSS_DICTION_TEST_module as
    select distinct action_id,action_note,cate,thingid,
           moduie_id,
           regexp_substr(channel_id,'[^,]+',1,level) as channel_id
    from OSS_DICTION_TEST_channel
    connect by
    level<=length(channel_id)-length(replace(channel_id,',',''))+1select * from OSS_DICTION_TEST_module