现有以下数据:
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语句直接实现。
请大虾们帮忙吧!
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语句直接实现。
请大虾们帮忙吧!
--写一个存储过程吧,参考
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;
动态列只有用循环写动态sql
union all
select id, C2 from xxx
....
--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;
也谢谢其他各位。
因为是涉及到大数据的计算。这只是计算中的某一步骤。
考虑到计算性能问题,也只能在每一处扣了。