oracle行列转换显示,Oracle中实现行列转换的方法

们在写SQL语句的时候经常需要用到行与列的转换问题,对于一个新手来说可能比较困难,其实你只要能够熟练运用Decode和Sum函数,这个问题就迎刃而解.

Create   table   test   (name   char(10),km   char(10),cj   Number)

insert   into   test   values('张三','语文',80)

insert   into   test   values('张三','数学',86)

insert   into   test   values('张三','英语',75)

insert   into   test   values('李四','语文',78)

insert   into   test   values('李四','数学',85)

insert   into   test   values('李四','英语',78)

commit;

怎样实现成这样:

name     语文     数学     英语

李四     78         85         83

张三     80         86         75

16:03:50   SQL>   select   *   from   test;

NAME               KM                                   CJ

----------   ----------   ----------

张三               语文                               80

张三               数学                               86

张三               英语                               75

李四               语文                               78

李四               数学                               85

李四               英语                               78

已选择6行。

已用时间:     00:   00:   00.47

16:03:55   SQL>   select   name,sum(decode(trim(km),'语文',cj,0))   语文,

16:03:58       2     sum(decode(trim(km),'数学',cj,0))   数学,

16:03:58       3     sum(decode(trim(km),'英语',cj,0))   英语

16:03:59       4     from   test   group   by   name;

NAME                           语文               数学               英语

----------   ----------   ----------   ----------

李四                               78                   85                   78

张三                               80                   86                   75

已用时间:     00:   00:   00.15

16:03:59   SQL>

[Q]如何实现行列转换

[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 student

2、不定列行列转换

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;即可

关于oracle中纵向记录横向显示的问题举例说明

最近在论坛里经常看到有朋友问这个问题,下面列举两个真实问答例子来说明 一下:

例一:

表如下:

ID  NO   Name  Course  Score

1   001  赵      语文   80

2   001  赵      数学   40

3   001  赵      英语   60

4   002  李      语文   50

5   002  李      数学   30

6   003  唐      语文   20

Sql语句执行结果如下:

NO         Name         AllCouse                   总分

001         赵          语文,数学,英语            180

002         李          语文,数学                  80

003         唐          语文                        20

答:

如果本例中的学科数量是有限的并且是已知的,则可以使用遍历的方法,用一个sql语句来实现:

select no,name,yw||xx||yy AllCouse,"语文"+"数学"+"英语" 总分 from

(select no,name, case when 语文<>0 then '语文' end yw,case when 数学<>0 then ',数学' end xx,case when 英语<>0 then ',英语' end yy,

"语文","数学","英语" from

(select no,name ,nvl(sum("语文"),0) "语文",nvl(sum("数学"),0) "数学",nvl(sum("英语"),0) "英语"

from (select no,name,

case when Course='语文'  then nvl(SUM(score),0) end "语文",

case when Course='数学'  then nvl(SUM(score),0) end "数学",

case when Course='英语'  then nvl(SUM(score),0) end "英语"

from lht_test

group by no,name,course) t

group by no,name) tt) ttt

例二:

table1(id varchar2(10), name varchar2(10))

id  name

1   aa

1   bb

1   cc

2   xx

3   yy

3   zz

...

想得到一个结果集如下:

id  names

1   aa+bb+cc

2   xx

3   yy+zz

...

答:

这种情况中,name的值是不可预知的,则只能通过存储过程来返回一个记录集来实现:

先定义一个记录集的type,

create or replace type t_name as object

(

Id              number(10),

Name varchar2(20),

);

create or replace type t_tab_names as table

of t_name;

create or replace procedure p_test (p_tTab_names out t_tab_names) as

i number;

flag number;

vtemp varchar2(100);

tname t_name;

begin

i:=0;

p_tTab_names:=new t_tab_names();

for v in (select id from table1 group by id) loop

i:=i+1;

flag:=0;

for vv in (select id,name from table1 where id=v.id) loop

if (flag=0) then

vtemp:=vv.name;

else

vtemp:=vtemp||'+'||vv.name;

end if;

flag:=1;

end loop;

tname.id:=v.id;

tname.name:=vtemp;

p_tTab_names.extend;

p_tTab_names(i):=tname;

end loop;

exception when others then

dbms_output.put_line(sqlerrm);

end p_test;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值