今天,主要是題目
--建表
--學生表:學號、姓名、性別、年齡
drop table t_student;
create table t_student(
sno varchar2(11) primary key,
sname varchar2(20) not null,
sex varchar2(3),
age number(3),
constraint c_1 check(sex in ('男','女'))
);
select * from t_student;
--教師表:編號、姓名
drop table t_teacher;
create table t_teacher(
tno varchar2(11) primary key,
tname varchar2(20) not null
);
select * from t_teacher;
--課程表:課程編號、課程名稱、教師編號
drop table t_course;
create table t_course(
cno varchar2(5) primary key,
cname varchar2(20) not null,
tno varchar2(11)
);
select * from t_course;
--成績表:學號、課程編號、成績
drop table t_grade;
create table t_grade(
sno varchar2(11),
cno varchar2(5),
grade number(3)
);
--!!!這裏成績採用的數據類型不對,導致後面的bug
--!!!但是這裏不影響知識點,就沒有改回來了
select * from t_grade;
--插入可能用到的數據
insert into t_student values('s001','李元芳','男',11);
insert into t_student values('s002','馬可波羅','男',20);
insert into t_student values('s003','孫尚香','女',16);
insert into t_student values('s004','公孫離','女',18);
insert into t_student values('s005','貂蟬','女',19);
insert into t_teacher values('t001','李白');
insert into t_teacher values('t002','韓信');
insert into t_course values('c001','打野教學','t001');
insert into t_course values('c002','刺客教學','t001');
insert into t_course values('c003','偷紅教學','t001');
insert into t_course values('c004','反藍教學','t002');
insert into t_course values('c005','刷龍教學','t002');
insert into t_grade values('s001','c001',80);
insert into t_grade values('s001','c002',59);
insert into t_grade values('s001','c004',60);
insert into t_grade values('s002','c001',70);
insert into t_grade values('s002','c002',50);
insert into t_grade values('s002','c003',40);
insert into t_grade values('s003','c003',50);
insert into t_grade values('s003','c005',70);
insert into t_grade values('s004','c001',55);
insert into t_grade values('s004','c002',50);
insert into t_grade values('s005','c002',90);
commit;
--1、查詢“c001”課程比“c002”課程成績高的所有學生的學號;
select g1.sno from t_grade g1,t_grade g2
where g1.sno = g2.sno
and g1.cno = 'c001'
and g2.cno = 'c002'
and g1.grade >g2.grade;
--測試數據需要
update t_grade set grade = 45 where cno = 'c001' and sno = 's004';
--2、查詢平均成績大於50 分的同學的學號和平均成績;
select sno,avg(grade) from t_grade
group by sno
having avg(grade)>50;
--3、查詢所有同學的學號、姓名、選課數、總成績;
select g.sno,
(select sname from t_student where sno = g.sno) as "姓名",
count(1) as "選課數",sum(grade) as "總成績"
from t_grade g
group by g.sno order by g.sno;
--4、查詢沒學過“李白”老師課的同學的學號、姓名;
update t_grade set cno = 'c004' where grade = 50 and sno = 's004';
select sno,sname from t_student where sno not in
(select distinct(sno) from t_grade where cno in
(select cno from t_course where tno in
(select tno from t_teacher where tname = '李白')
)
);
--李白教了哪些課,這些課哪些同學選了,除了這部分同學就是結果
--5、查詢學過“c001”並且也學過編號“c002”課程的同學的學號、姓名
update t_grade set cno = 'c004' where grade = 50 and sno = 's004';
select * from t_grade;
select t1.sno,(select sname from t_student where sno = t1.sno) as "姓名"
from
(select sno from t_grade where cno = 'c001') t1,
(select sno from t_grade where cno = 'c002') t2
where t1.sno = t2.sno;
--6、查詢學過“李白”老師所教的課的同學的學號、姓名;
select sno,sname from t_student where sno in
(select distinct(sno) from t_grade where cno in
(select cno from t_course where tno in
(select tno from t_teacher where tname = '李白')
)
);
--7、查詢課程編號“c002”的成績比課程編號“c001”課程低的所有同學的學號、姓名;
select g1.sno,(select sname from t_student where sno = g1.sno) as "姓名"
from t_grade g1,t_grade g2
where g1.sno = g2.sno
and g1.cno = 'c001'
and g2.cno = 'c002'
and g1.grade >=g2.grade;
--8、查詢所有課程成績小於60 分的同學的學號、姓名;
select sno,sname from t_student where sno not in
(select distinct(sno) from t_grade where grade>=60);
--9、查詢沒有學全所有課的同學的學號、姓名;
insert into t_grade values('s001','c003',60);
insert into t_grade values('s001','c005',60);
select g.sno,(select sname from t_student where sno = g.sno) as "姓名"
from t_grade g
group by g.sno
having count(1) <
(select count(1) from t_course);
--選修課程數不等於課程總數的學生即爲查詢結果
--10、查詢至少有一門課與學號爲“s003”的同學所學相同的同學的學號和姓名;
select distinct(g.sno),(select sname from t_student where sno = g.sno) as "姓名"
from t_grade g where g.cno in
(select cno from t_grade where sno = 's003')
and g.sno <> 's003';
--11、查詢至少學過學號爲“s003”同學所有一門課的其他同學學號和姓名;
--這題目和上一題不是一樣的??
--改一下:查詢學過學號爲“s003”同學所有課的其他同學學號和姓名;
select * from t_grade;
update t_grade set cno = 'c005' where grade = 65 and sno = 's004';
select s.sno,s.sname
from t_student s inner join t_grade g2
on (s.sno = g2.sno)
where g2.cno in
(select cno from t_grade g where g.sno = 's003')
group by s.sno,s.sname
having count(g2.cno) =
(select count(1) from t_grade g where g.sno = 's003')
and s.sno <> 's003';
--這個解決方案有點辣雞,不知道有沒有更好的辦法
--12、把“成績”表中“李白”老師教的課的成績都更改爲此課程的平均成績;
select * from t_grade;
update t_grade g set g.grade=
(select avg(grade) from t_grade where cno=g.cno)
where g.cno in
(select c.cno from t_course c where c.tno in(
select t.tno from t_teacher t where t.tname='李白')
);
--13、查詢和“s003”號的同學學習的課程完全相同的其他同學學號和姓名;
select s.sno,s.sname
from t_student s inner join t_grade g2
on (s.sno = g2.sno)
where g2.cno in
(select cno from t_grade g where g.sno = 's003')
group by s.sno,s.sname
having count(g2.cno) =
(select count(1) from t_grade g where g.sno = 's003')
and s.sno <> 's003'
and (select count(1) from t_grade g where g.sno = 's003') =
(select count(1) from t_grade g where g.sno = s.sno);
--和11題的主要區別就是,一個全學過,一個全相同,包含與相等的區別
--這裏肯定有更好的解決方案,但是懶得去寫了,有想法的可以留言給我
--14、查詢各科成績最高和最低的分:以如下形式顯示:課程ID,最高分,最低分
select cno ,max(grade),min(grade) from t_grade group by cno;
--15、按各科平均成績從低到高和及格率的百分數從高到低順序
select * from t_grade;
update t_grade set grade = 65 where cno = 'c004' and sno = 's002';
select g.cno as 課程id,avg(g.grade) as 平均成績,
100*sum(case when g.grade >=60 then 1 else 0 end)/count(1)||'%' as 及格率
from t_grade g
group by g.cno
order by avg(g.grade),
sum(case when g.grade>=60 then 1 else 0 end)/count(1) desc;
--16、查詢不同老師所教不同課程平均分從高到低顯示
select max(t.tno) as "教師id",max(t.tname) as "教師姓名",
max(c.cno) as "課程id",max(c.cname) as "課程名稱",avg(g.grade) as "平均成績"
from t_grade g,t_course c,t_teacher t
where c.cno=g.cno and c.tno = t.tno
group by c.cno
order by avg(g.grade) desc;
--17、統計列印各科成績,各分數段人數:課程ID,課程名稱,[100-85],[85-70],[70-60],[ <60]
select c.cno,c.cname,
(case when g.grade >=85 then '[100-85]'
when g.grade >=70 and g.grade <85 then '(85-70]'
when g.grade >=70 and g.grade <85 then '(70-60]'
else '<60'
end) as fd,
count(1)
from t_grade g,t_course c
where g.cno = c.cno
group by c.cno ,c.cname,
(case when g.grade >=85 then '[100-85]'
when g.grade >=70 and g.grade <85 then '(85-70]'
when g.grade >=70 and g.grade <85 then '(70-60]'
else '<60'
end)
order by c.cno,c.cname,fd;
rollback; --出現了誤操作
commit; --存檔
--18、查詢各科成績前2名的記錄:(不考慮成績並列情況)
select * from t_grade;
select sno,cno,grade from t_grade g1 where grade in
(select grade from t_grade g2
where g2.cno=g1.cno and rownum<=2)
order by g1.cno,g1.grade desc
--19、查詢每門課程被選修的學生數
select cno,count(cno) from t_grade group by cno;
--20、查詢出只選修了一門課程的全部學生的學號和姓名
select g.sno,(select sname from t_student where sno = g.sno) as "姓名"
from t_grade g group by sno having count(sno) = 1;
--21、查詢同名同性學生名單,並統計同名人數
insert into t_student values('s006','公孫離','男',29);
commit;
select * from t_student;
select sname,count(sname) as "人數" from t_student group by sname
having count(sname)>1;
--22、2001 年出生的學生名單(注:Student 表中Sage 列的類型是number)
select sno,sname,age,sex
from t_student
where age=
floor(months_between(sysdate,to_date('2001-01-01','yyyy-mm-dd'))/12);
--23、查詢每門課程的平均成績,結果按平均成績升序排列,平均成績相同時,按課程號降序排列
select cno,avg(grade) from t_grade
group by cno
order by avg(grade) desc;
--24、查詢平均成績大於85 的所有學生的學號、姓名和平均成績
select s.sno,s.sname,t.gr from t_student s right join
(select sno,avg(grade) as gr from t_grade group by sno having avg(grade)>65) t
on s.sno = t.sno
order by t.gr desc;
--25、查詢課程名稱爲“打野教學”,且分數低於60 的學生姓名和分數
select g.sno,(select sname from t_student where sno = g.sno) as "姓名" ,
g.grade from t_grade g where g.cno =
(select cno from t_course where cname = '打野教學')
and g.grade < 60;
--26、查詢所有學生的選課情況;
select s.sno,s.sname,g.cno,(select cname from t_course where cno = g.cno) as "課程名"
from t_student s left join t_grade g
on s.sno = g.sno;
--27、查詢任何一門課程成績在70 分以上的姓名、課程名稱和分數;
select g.sno,(select sname from t_student where sno = g.sno) as "姓名" ,
g.cno,(select cname from t_course where cno = g.cno) as "課程名",
grade
from t_grade g where grade > 70;
--28、查詢不及格的課程,並按課程號從大到小排列
select cno,sno from t_grade g where g.grade < 60 order by cno;
--29、查詢課程編號爲c001 且課程成績在80 分以上的學生的學號和姓名;
select sno,(select sname from t_student where sno = g.sno) as "姓名"
from t_grade g where cno = 'c001' and grade >=80;
--30、查詢選修“李白”老師所授課程的學生中,成績最高的學生姓名及其成績
select cno,sno,grade from t_grade where cno in
(select c.cno from t_course c where c.tno in
(select t.tno from t_teacher t where t.tname='李白')
)
order by cno ,grade desc;
--這題不會,看了下別人的思路,分組找最高的分數,
--再看誰對應這個分數,可以實現,但我總感覺這裏違背客觀事實
--31、查詢各個課程及相應的選修人數
select g.cno,(select cname from t_course where cno = g.cno) as "課程名",
count(1) from t_grade g group by cno order by cno;
--32、查詢不同課程成績相同的學生的學號、課程號、學生成績
select g1.*,g2.* from t_grade g1,t_grade g2
where g2.grade = g1.grade and g1.cno <> g2.cno ;
--33、查詢每門功課成績最好的前兩名
SELECT g1.* FROM t_grade g1 WHERE
(SELECT COUNT(1) FROM t_grade g2 WHERE
g1.cno=g2.cno AND g2.grade>=g1.grade)<=2
ORDER BY g1.cno,g1.grade DESC;
--34、統計每門課程的學生選修人數(超過2 人的課程才統計)。
--要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列
select cno,count(1) from t_grade
group by cno
having count(1) >=2
order by count(1) desc,cno;
--35、檢索至少選修兩門課程的學生學號
select sno,count(1) from t_grade
group by sno
having count(1) >=2
--36、查詢全部學生都選修的課程的課程號和課程名
--數據不支持,改成只差三個同學沒選修的課程
select cno,count(1) from t_grade group by cno
having count(1) >=
((select count(1) from t_student)- 3);
--37、查詢沒學過“李白”老師講授的任一門課程的學生姓名
select sno,(select sname from t_student where sno = g.sno) as "姓名"
from t_grade g where cno not in
(select c.cno from t_course c where c.tno in
(select t.tno from t_teacher t where t.tname='李白')
);
--38、查詢兩門以上不及格課程的同學的學號及其平均成績
select sno,count(cno) from t_grade
where grade < 60
group by sno
having count(cno) >= 2;
--39、檢索“c004”課程分數小於60,按分數降序排列的同學學號
insert into t_grade values('s002','c004',55);
insert into t_grade values('s003','c004',59);
commit;
select sno,grade from t_grade where cno = 'c004' and grade < 60;