现有以下数据:
id  C1  C3  C8  C9...C#
1   0   1   1   0 ...1
2   1   1   1   1 ...0
3   1   0   1   0 ...1
.............因为是动态列,列名除了固定列id外,其他列都是动态生成,规则为C#,#号为无规则的一串编号。现需要转换成如下数据结构id  group
1   3
1   8
1   #
2   1
2   3
2   8
2   9
3   1
3   8
3   #
.....
这里面的#号都是代表了数字。
也就是需要把原始的表中,C#为1的记录转化为(id,#)的数据格式。希望不要用循环的方式实现。
最好是能直接用sql语句直接实现。
请大虾们帮忙吧!

解决方案 »

  1.   

    --在列不定的情况下,一个sql语句不现实
    --写一个存储过程吧,参考
    CREATE OR REPLACE PROCEDURE col2row(i_tablename VARCHAR2, o OUT SYS_REFCURSOR) IS
    --i_tablename:你的表名,必须有ID列,其它列以C开头
    --o返回游标
      sqlstr VARCHAR2(32767) := '';
    BEGIN
      FOR i IN (SELECT *
                  FROM user_tab_columns t
                 WHERE t.TABLE_NAME = upper(i_tablename) AND
                       t.COLUMN_NAME LIKE 'C%') LOOP
        sqlstr := sqlstr || 'select id, substr(''' || i.column_name || ''',2) grp, nvl(' ||
                  i.column_name || ',''0'') cv FROM ' || i_tablename || ' UNION ALL ';
      END LOOP;
      sqlstr := 'select id,grp from (' || rtrim(sqlstr, ' UNION ALL ') || ') where cv<>''0''';
      OPEN o FOR sqlstr;
    END col2row;
      

  2.   

    希望不成立,^_^
    动态列只有用循环写动态sql
      

  3.   

     你的表的列数都不固定?一种方法,就是用程序/存储过程,读这个表的columns,然后生成这种union all的语句select id, C1 from xxx
    union all
    select id, C2 from xxx
    ....
      

  4.   

    CREATE OR REPLACE PROCEDURE col2row(i_tablename VARCHAR2, o OUT SYS_REFCURSOR) IS
    --i_tablename:你的表名,必须有ID列,其它列以C开头
    --o返回游标
      sqlstr VARCHAR2(32767) := '';
    BEGIN
      FOR i IN (SELECT *
                  FROM user_tab_columns t
                 WHERE t.TABLE_NAME = upper(i_tablename) AND
                       t.COLUMN_NAME LIKE 'C%') LOOP
        sqlstr := sqlstr || 'select id, substr(''' || i.column_name || ''',2) grp, nvl(' ||
                  i.column_name || ',''0'') cv FROM ' || i_tablename || ' UNION ALL ';
      END LOOP;
      sqlstr := 'select id,grp from (' || rtrim(sqlstr, ' UNION ALL ') || ') where cv<>''0''';
      OPEN o FOR sqlstr;
    END col2row;
      

  5.   

    多谢tangren。
    也谢谢其他各位。
    因为是涉及到大数据的计算。这只是计算中的某一步骤。
    考虑到计算性能问题,也只能在每一处扣了。