--1.学生表
Student(Sid,Sname,Sage,Ssex)?
--Sid 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别
--2.课程表?
Course(Cid,Cname,Tid)?
--Cid --课程编号,Cname 课程名称,Tid 教师编号
--3.教师表?
Teacher(Tid,Tname)
--Tid 教师编号,Tname 教师姓名
--4.成绩表?
SC(Sid,Cid,score)
--Sid 学生编号,Cid 课程编号,score 分数
测试数据
-- 学生表?Student
create table Student(Sid varchar(10),Sname nvarchar(10),Sage datetime,Ssex nvarchar(10))
insert into Student values('01' , N'赵雷' , '1990-01-01' , N'男')
insert into Student values('02' , N'钱电' , '1990-12-21' , N'男')
insert into Student values('03' , N'孙风' , '1990-05-20' , N'男')
insert into Student values('04' , N'李云' , '1990-08-06' , N'男')
insert into Student values('05' , N'周梅' , '1991-12-01' , N'女')
insert into Student values('06' , N'吴兰' , '1992-03-01' , N'女')
insert into Student values('07' , N'郑竹' , '1989-07-01' , N'女')
insert into Student values('08' , N'王菊' , '1990-01-20' , N'女')
-- 科目表 Course
create table Course(Cid varchar(10),Cname nvarchar(10),Tid varchar(10))
insert into Course values('01' , N'语文' , '02')
insert into Course values('02' , N'数学' , '01')
insert into Course values('03' , N'英语' , '03')
-- --教师表 Teacher
create table Teacher(Tid varchar(10),Tname nvarchar(10))
insert into Teacher values('01', N'张三')
insert into Teacher values('02', N'李四')
insert into Teacher values('03', N'王五')
-- 成绩表 SC
create table SC(Sid varchar(10),Cid varchar(10),score decimal(18,1))
insert into SC values('01' , '01' , 80)
insert into SC values('01' , '02' , 90)
insert into SC values('01' , '03' , 99)
insert into SC values('02' , '01' , 70)
insert into SC values('02' , '02' , 60)
insert into SC values('02' , '03' , 80)
insert into SC values('03' , '01' , 80)
insert into SC values('03' , '02' , 80)
insert into SC values('03' , '03' , 80)
insert into SC values('04' , '01' , 50)
insert into SC values('04' , '02' , 30)
insert into SC values('04' , '03' , 20)
insert into SC values('05' , '01' , 76)
insert into SC values('05' , '02' , 87)
insert into SC values('06' , '01' , 31)
insert into SC values('06' , '03' , 34)
insert into SC values('07' , '02' , 89)
insert into SC values('07' , '03' , 98)
练习题
-- 1. 查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
select distinct a.*,b.score as 01score,c.score as 02score
from student a inner join sc b on a.`SId`=b.`SId`
inner join sc c on b.`SId`=c.`SId`
where b.score > c.score
and b.`CId`=01
and c.`CId`=02
-- 1.1 查询同时存在" 01 "课程和" 02 "课程的情况
select distinct a.*,b.score as 01score,c.score as 02score
from student a inner join sc b on a.`SId`=b.`SId`
inner join sc c on b.`SId`=c.`SId`
where b.`CId`=01
and c.`CId`=02
-- 1.2 查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )
select * from
(select * from sc where sc.`CId`=02) as a
right join
(select * from sc where sc.`CId`=01) as b
on a.sid = b.sid
-- 1.3 查询不存在" 01 "课程但存在" 02 "课程的情况
select a.*,b.*
from sc a join sc b on a.`SId` = b.`SId`
where a.`CId` != 01 and b.`CId` = 02
-- 2. 查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
select a.`Sname`,avg(b.score) as avgScore
from student a join sc b on a.`SId`=b.`SId`
group by a.`SId`
having avg(b.score) > 60
-- 3. 查询在 SC 表存在成绩的学生信息
select distinct a.*
from student a join sc b on a.`SId` = b.`SId`
-- 4. 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
select a.*,sum(b.score) as sumScore
from student a left join sc b on a.`SId`=b.`SId`
group by a.`SId`
order by sum(b.score) desc
-- 4.1 查有成绩的学生信息
select distinct a.*
from student a join sc b on a.`SId`=b.`SId`
----
select *
from student a where exists (select sc.cid from sc where a.`SId`=sc.sid)
---
select *
from student a where a.`SId` in (select sc.sid from sc)
-- 5. 查询「李」姓老师的数量?
select a.*,count(*) as sum
from teacher a
where a.`Tname` like '李%'
-- 6. 查询学过「张三」老师授课的同学的信息?
select a.*
from student a,sc b,course c,teacher d
where a.`SId` = b.sid
and b.cid = c.`CId`
and c.`TId` = d.`Tid`
and d.`Tname` ='张三'
-----------
select a.*
from student a join sc b on a.`SId`=b.`SId`
join course c on b.`CId` = c.`CId`
join teacher d on c.`TId` = d.`Tid`
where d.`Tname`='张三'
-- 7. 查询没有学全所有课程的同学的信息?
select a.*,count(*)
from student a join sc b on a.`SId`=b.`SId`
join course c on b.`CId` = c.`CId`
group by a.`SId`
-- having count(*) >0
having count(*) < (select count(*) from course)
-- 8. 查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息?
select distinct a.*
from student a join sc b on a.`SId` = b.`sId`
join sc c on b.`CId`= c.`CId`
where c.`SId` = 01 and a.`SId` != 01
-- 9. 查询和" 01 "号的同学学习的课程完全相同的其他同学的信息?
select a.*
from student a join sc b on a.`SId`=b.`SId`
where b.`CId` in (
select c.`CId` from sc c where c.`SId` = 01
)
group by a.`SId`
having count(b.`CId`) = (select count(sc.`CId`) from sc where sc.sid=01)
-- 10. 查询没学过"张三"老师讲授的任一门课程的学生姓名?
select distinct a.*
from student a join sc b on a.`SId`=b.`SId`
join course c on b.`CId` = c.`CId`
join teacher d on c.`TId` = d.`Tid`
where d.`Tname`!='张三'
-- 11. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩?
select a.`SId`,a.`Sname`,avg(b.score)
from student a join sc b on a.`SId`=b.`SId`
where b.score<60
group by a.`SId`
having count(*) > 1
-- 12. 检索" 01 "课程分数小于 60,按分数降序排列的学生信息
select a.`SId`,a.`Sname`,avg(b.score)
from student a join sc b on a.`SId`=b.`SId`
where b.`CId`=01 and b.score<60
order by b.score desc
-- 13. 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
select * from sc b
join (
select c.`SId`,avg(c.score) as avsc
from sc c
group by c.score
) d
on b.`SId` = d.sid
order by avsc desc
-- 14.查询各科成绩最高分、最低分和平均分:
-- 以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
-- 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
-- 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
select
a.cou_id,
max(a.sco_degree) as 最高分,
min(a.sco_degree) as 最低分,
avg(a.sco_degree) as 平均分,
count(*) as 选修人数,
sum(case when a.sco_degree>=60 then 1 else 0 end)/count(*) as 及格率,
sum(case when a.sco_degree>=70 and a.sco_degree<80 then 1 else 0 end)/count(*) as 中等率,
sum(case when a.sco_degree>=80 and a.sco_degree<90 then 1 else 0 end)/count(*) as 优良率,
sum(case when a.sco_degree>=90 then 1 else 0 end)/count(*) as 优秀率
from score a
group by a.cou_id
order by count(*) desc,a.cou_id
-- 15.按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺
-- 用sc中的score和自己进行对比,来计算“比当前分数高的分数有几个
select a.cou_id,a.stu_id,a.sco_degree,count(b.sco_degree)+1 as rank
from score a
left join score b
on a.sco_degree < b.sco_degree and a.cou_id = b.cou_id
group by a.stu_id,a.cou_id,a.sco_degree
order by a.cou_id,rank asc
select cou_id,stu_id,sco_degree,row_number()over(partition by cou_id order by sco_degree desc) rank from score
order by cou_id,rank
select cou_id,stu_id,sco_degree,rank()over(partition by cou_id order by sco_degree desc)as rank from score
order by cou_id,rank
select cou_id,stu_id,sco_degree,dense_rank()over(partition by cou_id order by sco_degree desc)as rank from score
order by cou_id,rank
-- 15.1 按各科成绩进行排序,并显示排名, Score 重复时合并名次
select cou_id,stu_id,sco_degree,dense_rank()over(partition by cou_id order by sco_degree desc)as rank from score
order by cou_id,rank
-- 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺
set @crank = 0;
select b.stu_id, total,@crank := @crank +1 as rank
from (
select a.stu_id,sum(a.sco_degree) as total
from score a
group by a.stu_id
order by total desc
) b
select b.*,dense_rank()over(order by b.total desc) as rank from(
select stu_id,sum(sco_degree) as total from score group by stu_id
) b
order by rank
-- 16.1 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺
select b.*,rank()over(order by b.total desc) as rank from(
select stu_id,sum(sco_degree) as total from score group by stu_id
) b
order by rank
-- 17.统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比
select course.cou_name, course.cou_id,
sum(case when sc.sco_degree<=100 and sc.sco_degree>85 then 1 else 0 end) as "[100-85]",
sum(case when sc.sco_degree<=85 and sc.sco_degree>70 then 1 else 0 end) as "[85-70]",
sum(case when sc.sco_degree<=70 and sc.sco_degree>60 then 1 else 0 end) as "[70-60]",
sum(case when sc.sco_degree<=60 and sc.sco_degree>0 then 1 else 0 end) as "[60-0]"
from score as sc left join course
on sc.cou_id = course.cou_id
group by sc.cou_id;
-- 18.查询各科成绩前三名的记录
-- 计算比自己分数大的记录有几条,如果小于3 就select
select a.cou_id,a.stu_id,a.sco_degree
from score a
where (
select count(*) from score as b
where b.cou_id = a.cou_id and a.sco_degree <b.sco_degree
)< 3
order by a.cou_id asc, a.sco_degree desc;
-- 列出同一门课内所有分数比较的情况
select a.cou_id,a.stu_id,a.sco_degree
from score a
left join score b on a.cou_id = b.cou_id and a.sco_degree< b.sco_degree
group by a.cou_id,a.stu_id
having count(b.cou_id) <3
order by a.cou_id
--
select c.cou_id,c.stu_id,c.sco_degree
from(
select *,rank()over (partition by a.cou_id order by sco_degree desc) b
from score a
) c
where c.b<=3
order by c.cou_id,c.sco_degree desc
-- 19.查询每门课程被选修的学生数
select a.cou_id,count(a.stu_id) as num
from score a
group by a.cou_id
-- 20.查询出只选修两门课程的学生学号和姓名
select a.stu_id,a.stu_name
from student a
where a.stu_id in (
select b.stu_id
from score b
group by b.stu_id
having count(*) = 2
)
select a.stu_id,a.stu_name
from student a inner join score b on a.stu_id = b.stu_id
group by a.stu_id
having count(*)=2
-- 21.查询男生、女生人数
select a.stu_sex,count(8)
from student a
group by a.stu_sex
-- 22.查询名字中含有「风」字的学生信息
select *
from student
where stu_name like '%风%'
-- 23.查询同名同性学生名单,并统计同名人数
select stu_name, count(*) from student
group by stu_name
-- 24.查询 1990 年出生的学生名单
select stu_name,stu_birthday
from student
where year(stu_birthday) = 1990
-- 25.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
select a.cou_id,avg(a.sco_degree) as avcs
from score a
group by a.cou_id
order by avcs desc,a.cou_id
-- 26.查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
select a.stu_id,a.stu_name,avg(b.sco_degree)
from student as a inner join score as b on a.stu_id = b.stu_id
group by a.stu_id
having avg(b.sco_degree) >=85
-- 27.查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
select a.stu_id,a.stu_name,b.sco_degree
from student as a inner join score as b on a.stu_id = b.stu_id
inner join course as c on c.cou_id = b.cou_id
where c.cou_name="数学"
and b.sco_degree <60
-- 28.查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
select a.stu_id,a.stu_name,b.sco_degree
from student as a left join score as b on a.stu_id = b.stu_id
-- 29.查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
select a.stu_id,a.stu_name,b.sco_degree
from student as a left join score as b on a.stu_id = b.stu_id
where b.sco_degree>70
-- 30.查询不及格的课程
select * from score
where sco_degree< 60
group by cou_id;
-- 31.查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名
select a.stu_id,a.stu_name,b.cou_id,b.sco_degree
from student as a left join score as b on a.stu_id = b.stu_id
where b.sco_degree>=80 and b.cou_id =01
-- 32.求每门课程的学生人数
select b.stu_id,count(*)as 学生人数
from score b
group by b.cou_id
-- 33.成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
select * from score
where score.cou_id =(
select b.cou_id from course b where b.tea_id = (
select teacher.tea_id from teacher where teacher.tea_name ='张三'
)
)
order by score.sco_degree desc
limit 1
-- 34.成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
select * from (
select z.cou_id,z.stu_id,z.sco_degree,dense_rank()over(order by z.sco_degree desc) as rank from score z
where z.cou_id =(
select b.cou_id from course b where b.tea_id = (
select teacher.tea_id from teacher where teacher.tea_name ='张三'
)
)
) y
where y.rank = 1
-- 35.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
select *
from score a inner join score b on a.stu_id = b.stu_id
where a.cou_id != b.cou_id
and a.sco_degree = b.sco_degree
group by a.cou_id,a.stu_id
-- 36.查询每门功成绩最好的前两名
select *
from (
select *, row_number()over(partition by b.cou_id order by b.sco_degree desc ) as rank from score b
) c
where c.rank <3
order by c.cou_id,c.stu_id
-- 37.统计每门课程的学生选修人数(超过 5 人的课程才统计)。
select a.cou_id,count(*) as num
from score a
group by a.cou_id
having count(*)>5
-- 38.检索至少选修两门课程的学生学号
-- 39.查询选修了全部课程的学生信息
-- 40.查询各学生的年龄,只按年份来算
select student.stu_id as 学生编号,student.stu_name as 学生姓名,
timestampdiff(YEAR,student.stu_birthday,curdate()) as 学生年龄
from student
-- 41.按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
-- 42.查询本周过生日的学生
-- 43.查询下周过生日的学生
select *
from student
where weekofyear(student.stu_birthday)=weekofyear(curdate())+1;
-- 44.查询本月过生日的学生
-- 45.查询下月过生日的学生
select *
from student
where month(student.stu_birthday)=month(curdate())+1;