SQL经典练习题50--mysql

--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;
上一篇:SQL-sp_executesql


下一篇:c – MIDL更改接口名称