Oracle 行转列方法

在应用系统开发中我们经常会遇到行转列问题,尤其对于数据分析、报表系统中。本文将介绍在Oracle数据库中对数值、文本字段如何进行行转列。

首先我们创建一个测试表,表脚本为如下所示:

--创建表

create table item_score    

(

    code            varchar2(32)  not null,   --考号

    itemid          number(10),     --题号

    score           number(10,2),  --成绩

    score_level  varchar2(1)     --成绩等级A,B

);

 

--插入测试数据

declare
vscore number;
begin
  vscore:=dbms_random.value(0,10);
  insert into item_score(code, itemid, score, score_level)
  values('10001', 1,vscore,decode(sign(vscore-5),-1,'B','A'));
 
  vscore:=dbms_random.value(0,10);
  insert into item_score(code, itemid, score, score_level)
  values('10001', 2,vscore,decode(sign(vscore-5),-1,'B','A'));
 
  vscore:=dbms_random.value(0,10);
  insert into item_score(code, itemid, score, score_level)
  values('10002', 1,vscore,decode(sign(vscore-5),-1,'B','A'));
 
  vscore:=dbms_random.value(0,10);
  insert into item_score(code, itemid, score, score_level)
  values('10002', 2,vscore,decode(sign(vscore-5),-1,'B','A'));
  commit;
end;

 

--查询数据

select * from item_score

 

得到结果:

 

    CODE ITEMID SCORE SCORE_LEVEL
   10001 1          2.90     B

   10001 2          1.59     B
   10002 1          8.77     A
   10002 2          2.59     B

 

表item_score中将学生各题成绩横向存储的,但是在实际中往往需要看到如下成绩单:

 

考号   ,题目1, 等级1,题目2, ....

1001 ,得分 , 等级  ,得分, ...

1002 ,得分 , 等级  ,得分, ...

 

为得到以上查询结果我们需要进行行转列,就是需要生成一个交叉表.

 

1.行转列(itemid)的值字段(score)是数值型字段进行行转列.我们通常配合使用sum,decode来完成,但必须保证要进行转换的列的值对于分组列是唯一的.

select code --分组列
       ,sum(decode(itemid,1,score,0)) item_1 --题1
       ,sum(decode(itemid,2,score,0)) item_2 --题2
from item_score group by code order by code

执行以上语句我们就可以得到以下结果:

    CODE    ITEM_1    ITEM_2

   --------------------------------
   10002    8.77         2.59
   10001    2.9           1.59
2.行转列(itemid)的值字段(score_level)是文本型字段进行行转列.我们通常使用wmsys.wm_concat,decode函数配合使用.

select code   --分组列     
       ,wmsys.wm_concat(decode(itemid,1,score_level,'')) level_1
       ,wmsys.wm_concat(decode(itemid,2,score_level,'')) level_2
from item_score group by code order by code

执行以上语句我们就可以得到以下结果:

    CODE      LEVEL_1      LEVEL_2
   10001      B                 B
   10002      A                 B

合并1,2中的语句就可以得到我们想要的结果:

select code "考号"    
       ,sum(decode(itemid,1,score,0)) "第1题"
       ,wmsys.wm_concat(decode(itemid,1,score_level,'')) "第1题等级"
       ,sum(decode(itemid,2,score,0)) "第2题"
       ,wmsys.wm_concat(decode(itemid,2,score_level,'')) "第2题等级"
from item_score group by code order by code

执行以上语句我们就可以得到以下结果:

    考号     第1题     第1题等级      第2题      第2题等级
10001     2.9        B                 1.59        B
10002     8.77      A                 2.59        B

用以上两种方法基本可以解决我们常见的交叉表问题.当然很多报表组件(Crystal Reports,microsoft reports)等都提供交叉表功能,如果使用这些组件的话可以不用在数据库层面解决交叉表问题.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值