存储过程经典例题演示:按科目统计分数段的人数;把各科成绩显示在一条记录里。

本文介绍如何使用Oracle存储过程实现对学生多科目成绩的统计分析,包括按科目统计分数段的人数及按学生姓名整合各科成绩。

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

假设有张学生成绩表(CJ)如下 
[姓名] [学科] [成绩] 
张三 语文 80 
张三 数学 86 
张三 英语 75 
李四 语文 78 
李四 数学 85 
李四 英语 78 
...

现有需求如下:
(1)要求按科目统计分数段的人数。显示结果为:
[成绩]      [人数]
0<成绩<60      0 
60<成绩<80     0 
80<成绩<100    5
(2)要求根据姓名,把各科成绩显示在一条记录里。显示结果如下:
姓名             语文       数学       英语     总成绩
---------- ---------- ---------- ---------- ----------
李四               78         85         78        241
张三               80         86         75        241
总分              158        171        153       482 

使用存储过程(显示结果时可用dbms_output打印出来)实现这两个功能。

create table CJ(
  stuname VARCHAR2(50),
  subject VARCHAR2(50),
  score   NUMBER(8)
);
insert into CJ (stuname, subject, score) values ('张三', '语文', 80);
insert into CJ (stuname, subject, score) values ('张三', '数学', 86);
insert into CJ (stuname, subject, score) values ('张三', '英语', 75);
insert into CJ (stuname, subject, score) values ('李四', '语文', 78);
insert into CJ (stuname, subject, score) values ('李四', '数学', 85);
insert into CJ (stuname, subject, score)values ('李四', '英语', 78);
commit;

select * from cj;

1.按科目统计分数段的人数
create or replace procedure countScore(
    v_subject  in   cj.subject%type
)is
    less60 number(8);
    less80 number(8);
    less100 number(8);
begin
    select count(score) into less60 from cj where subject=v_subject and score<60;
    select count(score) into less80 from cj where subject=v_subject and score>=60 and score<80;
    select count(score) into less100 from cj where subject=v_subject and score>=80;
    
    dbms_output.put_line('[成绩]      [人数]');
    dbms_output.put_line('0<成绩<60      '||less60);
    dbms_output.put_line('60<成绩<80      '||less80);
    dbms_output.put_line('80<成绩<100      '||less100);
    
end;

set serveroutput on;

exec countScore('语文');


select 
    count(case when score<60 then 1 end) less60,
    count(case when score>=60 and score<80 then 1 end) less80,
    count(case when score>=80 then 1 end) less100
from cj where subject='语文'


2.要求根据姓名,把各科成绩显示在一条记录里。显示结果如下
姓名             语文       数学       英语   
---------- ---------- ---------- ---------- 
李四               78         85         78       
张三               80         86         75        

select * from cj;    

select stuname,
    max(case when subject='语文' then score end) 语文,
    max(case when subject='数学' then score end) 数学,
    max(case when subject='英语' then score end) 英语
from cj 
group by stuname;


create or replace procedure showScore
is
    cursor allscore is select stuname,
                            max(case when subject='语文' then score end) chinese,
                            max(case when subject='数学' then score end) math,
                            max(case when subject='英语' then score end) english
                        from cj  group by stuname;
    v_name cj.stuname%type;
    chinese_score cj.score%type;
    math_score cj.score%type;
    english_score cj.score%type;
    totoal_chinese_score cj.score%type:=0;
    totoal_math_score cj.score%type:=0;
    totoal_english_score cj.score%type:=0;
    
begin
    dbms_output.put_line('姓名          语文       数学       英语       总成绩');
    open allscore;
    loop
        fetch allscore into v_name,chinese_score,math_score,english_score;
        if allscore%notfound then exit;end if;
        dbms_output.put(v_name||'            ');
        dbms_output.put(chinese_score||'      ');
        dbms_output.put(math_score||'      ');
        dbms_output.put(english_score||'      ');
        dbms_output.put((chinese_score+math_score+english_score));
        
        dbms_output.put_line('');
        
        totoal_chinese_score:=totoal_chinese_score+chinese_score;
        totoal_math_score:=totoal_math_score+math_score;
        totoal_english_score:=totoal_english_score+english_score;
        
        
    end loop;
    if allscore%isopen then close allscore;end if;
    dbms_output.put_line('总分              '||totoal_chinese_score||'        '||totoal_math_score||'        '||totoal_english_score||'       '||(totoal_chinese_score+totoal_math_score+totoal_english_score));
end;

exec showScore
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好好羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值