oracle 行变列

本文通过SQL语句展示了如何从学生、课程及成绩表中查询并汇总学生的各科成绩、总分及平均分等内容,同时介绍了使用DECODE函数进行行转列的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

select * from kind;

create table student (sno int,sname varchar2(8))

insert into student
select 1,'tom' from dual union
select 2,'jack' from dual union
select 3,'jerry' from dual union
select 4, 'wendy' from dual union
select 5 , 'sorry' from dual


create table courses (c_no int , c_name varchar2(8))

insert into courses
select 1,'语文' from dual union
select 2,'数学' from dual union
select 3,'英语' from dual


create table score (sno int ,c_no int ,mark int)

insert into score
select 1,1,60 from dual union
select 1,2,80 from dual union
select 1,3,100 from dual union
select 2,1,90 from dual union
select 2,2,80 from dual union
select 2,3,65 from dual union
select 3,1,50 from dual union
select 3,2,86 from dual union
select 3,3,90 from dual union
select 4,1,45 from dual union
select 4,2,86 from dual union
select 4,3,100 from dual union
select 5,1,20 from dual union
select 5,2,89 from dual union
select 5,3,90 from dual

select s.sno 学号,s.sname 姓名 /*,decode(c.c_name,'语文',score.mark) 语文 */from student s,courses c,score score group by s.sno,s.sname


select sum(decode(c.c_name,'语文',sco.mark)) 语文,sum(decode(c.c_name,'数学',sco.mark)) 数学,sum(decode(c.c_name,'英语',sco.mark)) 英语 from courses c  left outer join  score  sco on sco.c_no=c.c_no

 

select a.no,语文,英语,数学,(语文+数学+英语)as 总成绩,(语文+数学+英语)/3 as 平均成绩,(3-fnum)*100/3 as 及格率 from
(select no,sco as 语文 from test1017 where name='语文') a join (select no,sco as 英语 from test1017 where name='英语') b on a.no=b.no
join (select no,sco as 数学 from test1017 where name='数学') c on b.no=c.no
left join (select no,count(*)as fnum from test1017 where sco<60 group by no) d on c.no=d.no

 


select decode(c_name,'语文',1),decode(c_name,'数学',1) from score,courses where  score.c_no=courses.c_no group by score.c_no,courses.c_name

select * from score s,student stu,courses c where s.sno=stu.sno and s.c_no=c.c_no


select distinct decode(c_name,'语文',1) 语文 ,decode(c_name,'数学',1) 数学 from score right outer join courses on courses.c_no=score.c_no--where  score.c_no=courses.c_no

 


select* from courses;


select * from
(select sname s_name from student group by sname) left outer join
(select sname,语文,数学,英语 from (
select sno,decode(c_name,'语文',mark) 语文, decode(c_name,'数学',mark) 数学,decode(c_name,'英语',mark) 英语 from courses right outer join score on courses.c_no=score.c_no
) right outer join student on student.sno=sno) on s_name=sname  --group by student.sname


--通过观察我们看的出其中有两个重点一个是行变列一个是连接分组然后并行(用组合函数)注:并行我们可以用组合函数SUM()分列可用分析函数DECODE得新列
--根据题意可知要行变列所以使用分析函数DECODE通过相等来设列而列值通过两表连接使SCORE中的MARK做值
--通过第一步思路要进行两表连接那么用什么方式呢因为各人各科成绩是不一样的而又列中的值是成绩那就用对成绩表做全查的右外连接
--经过第一步我们可以得到15条记录而其中SNO重复的可知我们要分组正好可以得到学生名字因为SNO同SNAME一一对应的但如果在
--select sno s_no,decode(c_name,'语文',mark) 语文, decode(c_name,'数学',mark) 数学,decode(c_name,'英语',mark) 英语 from courses right outer join score on courses.c_no=score.c_no语句
--分组的话那就要在所有的列上加组函数如:SUM()的啊那就成了一行了与我们的想法又不同了如何解决呢那我们就不能在上面语句上分组了
--我们知道分组对FROM句中是不起作用的那可不可以先分了组再把对应数据的数据查出来呢正好可以通过连表把SNAME也查出来(注意SELECT FROM WHERE GROUP BY ODERY BY 执行顺序是先GROUP BY 再SELECT 然后WHERE 最后 ORDER BY 的)
--通过表连接在外层上GROUP BY 后再组合函数


select sname 姓名,语文,数学,英语, (语文+数学+英语) 总分 from (
select sname ,sum(语文) 语文,sum(数学) 数学,sum(英语) 英语 from (
select sno s_no,decode(c_name,'语文',mark) 语文, decode(c_name,'数学',mark) 数学,decode(c_name,'英语',mark) 英语 from courses right outer join score on courses.c_no=score.c_no
),student where s_no=student.sno group by student.sname
)
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值