SQL练习50题(基于MySQL)前25题

#--学生表
create table student(
    s_id vaechar(20),
    s_name vaechar(20) not NULL,
    s_birth vaechar(20) not NULL,
    s_sex vaechar(10) not NULL,
    constraint pk_student PRIMARY KEY (s_id))

#--课程表
create table  course(
    c_id  vaechar(20),
    c_name vaechar(20) not NULL DEFAULT '',
    t_id vaechar(20) not NULL,
    PRIMARY KEY(c_id))

#--教师表
create table teacher(
    t_id vaechar(20),
    t_name vaechar(20) not NULL DEFAULT '',
    PRIMARY KEY(t_id))

#--成绩表
create table score(
    s_id varchar(20),
    c_id  varchar(20),
    s_score int(3),
    PRIMARY KEY(s_id,c_id))

alter table teacher convert to character set utf8

#--插入学生表测试数据
insert into student values('01' , '赵雷' , '1990-01-01' , '');
insert into student values('02' , '钱电' , '1990-12-21' , '');
insert into student values('03' , '孙风' , '1990-05-20' , '');
insert into student values('04' , '李云' , '1990-08-06' , '');
insert into student values('05' , '周梅' , '1991-12-01' , '');
insert into student values('06' , '吴兰' , '1992-03-01' , '');
insert into student values('07' , '郑竹' , '1989-07-01' , '');
insert into student values('08' , '王菊' , '1990-01-20' , '');
#--课程表测试数据
insert into course values('01' , '语文' , '02');
insert into course values('02' , '数学' , '01');
insert into course values('03' , '英语' , '03');

#--教师表测试数据
insert into teacher values('01' , '张三');
insert into teacher values('02' , '李四');
insert into teacher values('03' , '王五');

#--成绩表测试数据
insert into score values('01' , '01' , 80);
insert into score values('01' , '02' , 90);
insert into score values('01' , '03' , 99);
insert into score values('02' , '01' , 70);
insert into score values('02' , '02' , 60);
insert into score values('02' , '03' , 80);
insert into score values('03' , '01' , 80);
insert into score values('03' , '02' , 80);
insert into score values('03' , '03' , 80);
insert into score values('04' , '01' , 50);
insert into score values('04' , '02' , 30);
insert into score values('04' , '03' , 20);
insert into score values('05' , '01' , 76);
insert into score values('05' , '02' , 87);
insert into score values('06' , '01' , 31);
insert into score values('06' , '03' , 34);
insert into score values('07' , '02' , 89);
insert into score values('07' , '03' , 98);
#-- 1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数
select *
from student st inner join score sc
on st.s_id = sc.s_id and sc.c_id = '01'
left outer join score s
on st.s_id = s.s_id and s.c_id = '02'
where sc.s_score > s.s_score;

#-- 2、查询"01"课程比"02"课程成绩低的学生的信息及课程分数
select *
from student st inner join score sc
on st.s_id = sc.s_id and sc.c_id = '01'
left join score s
on st.s_id = s.s_id and s.c_id = '02'
where sc.s_score < s.s_score;

#-- 3、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩
select s.s_id,  st.s_name, round(sum(s.s_score)/count(*),2) avg_score
from 
score s left join student st
on s.s_id = st.s_id
group by s.s_id
having sum(s.s_score)/count(*) >= 60

#-- 5、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
select st.s_id, st.s_name, count(s.c_id), sum(s.s_score)
from
student st left join score s
on st.s_id = s.s_id
group by st.s_id;

#-- 6、查询"李"姓老师的数量
select count(*)
from teacher
where t_name like '李%'

#-- 7、查询学过"张三"老师授课的同学的信息 
select t.t_name, st.*
from score s left join course c
on s.c_id = c.c_id
left join teacher t
on c.t_id = t.t_id
left join student st
on s.s_id = st.s_id
where t.t_id = '01'
group by st.s_name
order by s.s_id

#-- 8、查询没学过"张三"老师授课的同学的信息
select *
from student
where s_id not in
(select s.s_id
from score s left join course c
on s.c_id = c.c_id
left join teacher t
on c.t_id = t.t_id
left join student st
on s.s_id = st.s_id
where t.t_id = '01'
group by st.s_name
order by s.s_id)

#-- 9、查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息
select *
from score s inner join student st
on s.s_id = st.s_id
where s.c_id = '01' or s.c_id = '02'
group by s.s_id
having count(*)>1

#-- 10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息
#--方法一
select *
from(
select s.s_id, s.c_id, st.s_name, st.s_birth 
from score s inner join student st
on s.s_id = st.s_id
where s.c_id = '01' or s.c_id = '02'
group by s.s_id
having count(*) = 1
) a
where a.c_id = '01'
#--方法二
select *
from student st
where st.s_id in (select s_id from score where c_id = '01')
and st.s_id not in (select s_id from score where c_id = '02');
#--11、查询没有学全所有课程的同学的信息 
select *
from student st
where st.s_id  not in (
select s_id from score group by s_id having count(*) =3)

#-- 12、查询至少有一门课与学号为"01"的同学所学相同的同学的信息 
select * from student
where s_id in
(select b.s_id from
(select s_id, c_id from score where s_id = '01') a
cross join
(select s_id, c_id from score where s_id != '01') b
where a.c_id = b.c_id
group by b.s_id)

#-- 13、查询和"01"号的同学学习的课程完全相同的其他同学的信息 
select * from student
where s_id in    
(select b.s_id from
(select s_id, c_id from score where s_id = '01') a
cross join
(select s_id, c_id from score where s_id != '01') b
where a.c_id = b.c_id
group by b.s_id
having count(*) = 3)

#-- 14、查询没学过"张三"老师讲授的任一门课程的学生姓名 
select * from student
where s_id not in
(select s.s_id
from score s inner join course c
on s.c_id = c.c_id
inner join teacher t
on c.t_id = t.t_id
where t.t_name = '张三')

#-- 15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
select st.* , a.avg_score
from student st inner join
(select s_id, sum(s_score)/count(*) avg_score from score
where s_score < 60
group by s_id
having count(*) >= 2) a
where st.s_id = a.s_id

#-- 16、检索"01"课程分数小于60,按分数升序排列的学生信息
select * from student st
inner join
(select s_id, s_score from score
where c_id = '01' and s_score < 60) s
on st.s_id = s.s_id
order by s.s_score asc

#-- 17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
--形式一
select st.s_id, st.s_name, s.s_score, sc.sum_score from student st
left join score s
on st.s_id = s.s_id
left join 
(select s_id, sum(s_score) sum_score from score
group by s_id) sc
on st.s_id = sc.s_id
order by sc.sum_score desc
--形式二
select s.s_id,
(select s_score from score where s_id = s.s_id and c_id = '01') languages,
(select s_score from score where s_id = s.s_id and c_id = '02') maths,
(select s_score from score where s_id = s.s_id and c_id = '03') english,
avg(s.s_score) avg_score
from score s
group by s.s_id
order by avg_score desc

#-- 18.查询各科成绩最高分、最低分和平均分:
#--    以如下形式显示:
#--    课程ID,课程name,最高分,最低分,平均分,
#--    及格率,中等率,优良率,优秀率
#--    及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90    
select s.c_id,c.c_name, max(s.s_score), min(s.s_score), avg(s.s_score),
    sum(case when s.s_score >= 60 then 1 else 0 end)/
    sum(case when s.s_score then 1 else 0 end) a,
    sum(case when s.s_score between 70 and 80 then 1 else 0 end)/
    sum(case when s.s_score then 1 else 0 end) b,
    sum(case when s.s_score between 80 and 90 then 1 else 0 end)/
    sum(case when s.s_score then 1 else 0 end) c,
    sum(case when s.s_score >= 90 then 1 else 0 end)/
    sum(case when s.s_score then 1 else 0 end) d
from score s
left join 
(select *
from course) c
on s.c_id = c.c_id
group by s.c_id
#--注意标注代码的异同点
select s.c_id,c.c_name, max(s.s_score), min(s.s_score), avg(s.s_score),
    sum(case when s.s_score >= 60 then 1 else 0 end)/
    sum(case when s.s_score then 1 else 0 end) a,
    sum(case when s.s_score between 70 and 80 then 1 else 0 end)/
    sum(case when s.s_score then 1 else 0 end) b,
    sum(case when s.s_score between 80 and 90 then 1 else 0 end)/
    sum(case when s.s_score then 1 else 0 end) c,
    sum(case when s.s_score >= 90 then 1 else 0 end)/
    sum(case when s.s_score then 1 else 0 end) d
from score s
left join 
course c
on s.c_id = c.c_id
group by s.c_id

#-- 19、按各科成绩进行排序,并显示排名
set @rang := 0;
select *, @rang := @rang + 1
from score
order by s_score desc

#-- 20、查询学生的总成绩并进行排名
set @rang := 0;
select a.s_id, a.sum_score, @rang := @rang + 1
from 
(select s_id, sum(s_score) sum_score from score
group by s_id
order by sum_score desc) a
#-- 21、查询不同老师所教不同课程平均分从高到低显示
select s.s_id, t.t_name, s.c_id, avg(s.s_score) avg_score
from score s left outer join course c
on s.c_id = c.c_id
left outer join teacher t
on c.t_id = t.t_id
group by s.c_id
order by avg(s.s_score) desc

#-- 22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
set @one := 0;
set @two := 0;
set @three := 0;
select s.s_id, st.s_name, st.s_birth, st.s_sex, s.rang, s.s_score
from
(select s_id, c_id, s_score, @one :=@one + 1 rang
from score
where c_id = '01'
order by s_score desc) s
join student st
on s.s_id = st.s_id
where s.rang = 2 or s.rang = 3
union all
select s.s_id, st.s_name, st.s_birth, st.s_sex, s.rang, s.s_score
from
(select s_id, c_id, s_score, @two :=@two + 1 rang
from score
where c_id = '02'
order by s_score desc) s
join student st
on s.s_id = st.s_id
where s.rang = 2 or s.rang = 3
union all
select s.s_id, st.s_name, st.s_birth, st.s_sex, s.rang, s.s_score
from
(select s_id, c_id, s_score, @three :=@three + 1 rang
from score
where c_id = '03'
order by s_score desc) s
join student st
on s.s_id = st.s_id
where s.rang = 2 or s.rang = 3

#-- 23、统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比
select a.c_id, co.c_name, a.A, a.p,b.B, b.p,c.C,c.p,d.D,d.p from
(select c_id, sum(case when s_score > 85 and s_score <= 100 then 1 else 0 end) A,
100 * sum(case when s_score > 85 and s_score <= 100 then 1 else 0 end) / count(*) p
from score
group by c_id) a
left join
(select c_id, sum(case when s_score > 70 and s_score <= 85 then 1 else 0 end) B,
100 * sum(case when s_score > 70 and s_score <= 85 then 1 else 0 end) / count(*) p
from score
group by c_id) b
on a.c_id = b.c_id
left join
(select c_id, sum(case when s_score > 60 and s_score <= 70 then 1 else 0 end) C,
100 * sum(case when s_score > 60 and s_score <= 70 then 1 else 0 end) / count(*) p
from score
group by c_id) c
on a.c_id = c.c_id
left join
(select c_id, sum(case when s_score > 0 and s_score <= 60 then 1 else 0 end) D,
100 * sum(case when s_score > 0 and s_score <= 60 then 1 else 0 end) / count(*) p
from score
group by c_id) d
on a.c_id = d.c_id
left join
(select * from course) co
on a.c_id = co.c_id

#-- 24、查询学生平均成绩及其名次
#--一、
set @i = 0;
set @j = 0;
set @avg_s = 0;
select s.s_id, 
@i := @i + 1 '不保留空缺排名',
@j := (case when @avg_s = s.avg_score then @j else @i end) '保留空缺排名',
@avg_s := s.avg_score '平均分',
s.avg_score
from
(select s_id, avg(s_score) avg_score from score
group by s_id
order by avg_score desc)s
#--二、
select a.s_id,
@i:=@i+1 as '不保留空缺排名',
@k:=(case when @avg_score=a.avg_s then @k else @i end) as '保留空缺排名',
@avg_score:=avg_s as '平均分'
from (select s_id,ROUND(AVG(s_score),2) as avg_s from score GROUP BY s_id ORDER BY avg_s DESC)a,(select @avg_score:=0,@i:=10,@k:=0)b;

#-- 25、查询各科成绩前三名的记录
#-- 1.选出sc表比s表成绩大的所有组
#-- 2.选出比当前id成绩大的 小于三个的
select * from 
score s left join score sc
on s.c_id = sc.c_id and s.s_score < sc.s_score
group by s.s_id, s.c_id having count(sc.s_id) < 3
order by s.c_id,s.s_score desc

 

posted @ 2019-07-09 15:10  aioverg  阅读(237)  评论(0编辑  收藏  举报