[A]1、固定列数的行列转换
如
student subject grade
---------------------------
student1 语文 80
student1 数学 70
student1 英语 60
student2 语文 90
student2 数学 80
student2 英语 100
……
转换为
语文 数学 英语
student1 80 70 60
student2 90 80 100
……
语句如下:
select student,sum(decode(subject,'语文', grade,null)) "语文",
sum(decode(subject,'数学', grade,null)) "数学",
sum(decode(subject,'英语', grade,null)) "英语"
from table
group by student2、不定列行列转换
如
c1 c2
--------------
1 我
1 是
1 谁
2 知
2 道
3 不
……
转换为
1 我是谁
2 知道
3 不
这一类型的转换必须借助于PL/SQL来完成,这里给一个例子
CREATE OR REPLACE FUNCTION get_c2(tmp_c1 NUMBER)
RETURN VARCHAR2
IS
Col_c2 VARCHAR2(4000);
BEGIN
FOR cur IN (SELECT c2 FROM t WHERE c1=tmp_c1) LOOP
Col_c2 := Col_c2||cur.c2;
END LOOP;
Col_c2 := rtrim(Col_c2,1);
RETURN Col_c2;
END;
/
SQL> select distinct c1 ,get_c2(c1) cc2 from table;即可
如
student subject grade
---------------------------
student1 语文 80
student1 数学 70
student1 英语 60
student2 语文 90
student2 数学 80
student2 英语 100
……
转换为
语文 数学 英语
student1 80 70 60
student2 90 80 100
……
语句如下:
select student,sum(decode(subject,'语文', grade,null)) "语文",
sum(decode(subject,'数学', grade,null)) "数学",
sum(decode(subject,'英语', grade,null)) "英语"
from table
group by student2、不定列行列转换
如
c1 c2
--------------
1 我
1 是
1 谁
2 知
2 道
3 不
……
转换为
1 我是谁
2 知道
3 不
这一类型的转换必须借助于PL/SQL来完成,这里给一个例子
CREATE OR REPLACE FUNCTION get_c2(tmp_c1 NUMBER)
RETURN VARCHAR2
IS
Col_c2 VARCHAR2(4000);
BEGIN
FOR cur IN (SELECT c2 FROM t WHERE c1=tmp_c1) LOOP
Col_c2 := Col_c2||cur.c2;
END LOOP;
Col_c2 := rtrim(Col_c2,1);
RETURN Col_c2;
END;
/
SQL> select distinct c1 ,get_c2(c1) cc2 from table;即可
select year,month,unitid,name1 value from table1
union all
select year,month,unitid,name2 value from table1
union all
select year,month,unitid,name3 value from table1
union all
...
select year,month,unitid,namen value from table1;
select year,month,unitid
,decode(colseq,1,name1_value,2,name2_value,3,name3_value....
from table1,(select rownum colseq from temp where rownum<=列数)其中temp表为任一记录数>=列数的表。2.不固定时
如果能用一个sql搞定,相信竖表转横表也能。
改进一下上面:
select year,month,unitid,'name1' as name, name1 as value from table1
union
select year,month,unitid,'name2' as name, name2 as value from table1
union
select year,month,unitid,'name3' as name, name3 as value from table1
union
select year,month,unitid,'name4' as name, name4 as value from table1
union
.........
用存储过程也不好处理(包括动态SQl),因为是行的话,可以用Fetch,这样可能将行循环处理完。但列呢?pl/sql中好像没有col.next、col(i)之类的写法可以将列进行循环。即使从数据字典中得到了表的列数和列名,也无法用动态SQL拼成SQL执行。
例如:
先定义了数据的游标,
再定义了数据字典列名的游标取到了列名。
SQL := 'insert into tableA(col1) values('||数据游标.||列名;-------关键在于数据游标和列名无法组合。
考虑在前台处理,一般都有col.count、col(i)之类。
另一方面可以获取表的列信息 select * from user_tab_cols相对而言,列转行会比行转列简单一些
对于楼主的table1,我们可以取到列名有'name1','name2','name3','name4','name5'……
关键是游标A(对应table1的数据游标)无法与得到的列名(文本)组合。
因为在用动态SQL时,应
SQL := 'insert into tableA(col1) values('||游标A.||'name1'……(无法组合)
但你不能把游标A也写为文本:
SQL := 'insert into tableA(col1) values(游标A.name1)';(无法执行)