日期:2014-05-16  浏览次数:20828 次

行转列,列转行的问题

select id,max(decode(course,'语文',score,'0')) 语文,
max(decode(course,'数学',score,'0')) 数学,
max(decode(course,'英语',score,'0')) 英语
from test_students group by id;--行转列

select * from (
select id,'语文' subject,语文 score from test_students1 where 语文<>0
union
select id,'数学' subject,数学 score from test_students1 where 数学<>0
union
select id,'英语' subject,英语 score from test_students1 where 英语<>0)
order by id,case subject when '语文' then 1 when '数学' then 2 when '英语' then 3 end; --列转行

如果数据量更多,那么岂不是要写很多行.oracle有没有对应函数或者包,能够完成这种工作呢?
这是test_students表,源表

这是test_students1表
  

------解决方案--------------------

with test_students as(
select 1 id,90 语文,100 数学,12 英语 from dual union all
select 2,34,34,23 from dual union all
select 3,0,33,12 from dual union all
select 4,5,5,5 from dual)
select regexp_substr(str, '[^,]+', 1, rownum) str1
  from (select wmsys.wm_concat(id 
------解决方案--------------------
 '
------解决方案--------------------

------解决方案--------------------
 '语文
------解决方案--------------------

------解决方案--------------------
 语文 
------解决方案--------------------
 ',' 
------解决方案--------------------
 id 
------解决方案--------------------

                               '
------解决方案--------------------
数学' 
------解决方案--------------------
 '
------解决方案--------------------

------解决方案--------------------
 数学 
------解决方案--------------------
 ',' 
------解决方案--------------------
 id 
------解决方案--------------------
 '
------解决方案--------------------
英语' 
------解决方案--------------------
 '
------解决方案--------------------

------解决方案--------------------
 英语) str
          from test_students) t
connect by rownum <= (length(regexp_replace(str, '[^,]+', 1)) + 1) / 2

结果:

STR1
--------------------------------------------------------------------------------
1
------解决方案--------------------
语文
------解决方案--------------------
90
1
------解决方案--------------------
数学
------解决方案--------------------
100
1<