【MySQL】基础练习题
习题参考:https://blog.csdn.net/qq_41936662/article/details/80393172
数据库准备
建表语句
学生表 student
CREATE TABLE `student` (
`s_id` varchar(20) NOT NULL,
`s_name` varchar(20) NOT NULL DEFAULT '',
`s_brith` varchar(20) NOT NULL DEFAULT '',
`s_sex` varchar(10) NOT NULL DEFAULT '',
PRIMARY KEY (`s_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
教师表 teacher
CREATE TABLE `teacher` (
`t_id` varchar(20) NOT NULL,
`t_name` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`t_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
课程表 course
CREATE TABLE `course` (
`c_id` varchar(20) NOT NULL,
`c_name` varchar(20) NOT NULL DEFAULT '',
`t_id` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
成绩表 score
CREATE TABLE `score` (
`s_id` varchar(20) NOT NULL,
`c_id` varchar(20) NOT NULL,
`s_score` int(3) DEFAULT NULL,
PRIMARY KEY (`s_id`,`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
数据插入
学生表 student
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', '吴兰', '1991-03-01', '女');
INSERT INTO `student` VALUES ('07', '郑竹', '1989-07-01', '女');
INSERT INTO `student` VALUES ('08', '王菊', '1990-01-20', '女');
教师表 teacher
INSERT INTO `teacher` VALUES ('01', '张三');
INSERT INTO `teacher` VALUES ('02', '李四');
INSERT INTO `teacher` VALUES ('03', '王五');
课程表 course
INSERT INTO `course` VALUES ('01', '语文', '02');
INSERT INTO `course` VALUES ('02', '数学', '01');
INSERT INTO `course` VALUES ('03', '英语', '03');
成绩表 score
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', '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 ('05', '03', '87');
INSERT INTO `score` VALUES ('06', '01', '31');
INSERT INTO `score` VALUES ('06', '02', '40');
INSERT INTO `score` VALUES ('06', '03', '45');
INSERT INTO `score` VALUES ('07', '01', '89');
INSERT INTO `score` VALUES ('07', '02', '90');
INSERT INTO `score` VALUES ('07', '03', '50');
INSERT INTO `score` VALUES ('08', '01', '50');
INSERT INTO `score` VALUES ('08', '02', '50');
INSERT INTO `score` VALUES ('08', '03', '50');
习题
查询"01"课程比"02"课程成绩高的学生的信息及课程分数
SELECT
a.*,
b.s_score AS 01_score,
c.s_score AS 02_score
FROM
student a
INNER JOIN score b ON a.s_id = b.s_id AND b.c_id = '01'
INNER JOIN score c ON a.s_id = c.s_id AND c.c_id = '02'
WHERE
b.s_score > c.s_score
查询"01"课程比"02"课程成绩低的学生的信息及课程分数
SELECT a.* ,b.s_score as 01_score, c.s_score as 02_score
from student a
INNER JOIN score b on a.s_id = b.s_id and b.c_id = '01'
INNER JOIN score c on a.s_id = c.s_id and c.c_id = '02'
where b.s_score<c.s_score
1,2题的另一种SQL
SELECT a.* ,b.s_score as 01_score, c.s_score as 02_score
from student a,score b ,score c
where a.s_id = b.s_id and a.s_id = c.s_id and b.c_id = '01' and c.c_id='02' and b.s_score<c.s_score
查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩
SELECT student.s_id,student.s_name,ROUND(AVG(score.s_score),2) as 'avg_score'
from student
INNER JOIN score on student.s_id = score.s_id
GROUP BY score.s_id
HAVING ROUND(AVG(score.s_score),2)>=60
查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩
-- (包括有成绩的和无成绩的)
SELECT
b.s_id,
b.s_name,
ROUND(AVG(a.s_score), 2) AS avg_score
FROM
student b
LEFT JOIN score a ON b.s_id = a.s_id
GROUP BY
b.s_id,
b.s_name
HAVING
ROUND(AVG(a.s_score), 2) < 60
UNION
SELECT
a.s_id,
a.s_name,
0 AS avg_score
FROM
student a
WHERE
a.s_id NOT IN (
SELECT DISTINCT
s_id
FROM
score
);
查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
SELECT student.s_id ,student.s_name ,count(score.c_id),SUM(score.s_score)
from student
LEFT JOIN score on student.s_id = score.s_id
GROUP BY student.s_id ,student.s_name
查询"李"姓老师的数量
SELECT teacher.t_name ,count(1)
from teacher
GROUP BY teacher.t_name
HAVING teacher.t_name like '李%'
select count(t_id) from teacher where t_name like '李%';
查询学过"张三"老师授课的同学的信息
SELECT student.*
from score
INNER JOIN student on score.s_id =student.s_id
INNER JOIN course on score.c_id = course.c_id
INNER JOIN teacher on course.c_id= teacher.t_id
where teacher.t_name like '张三'
select a.* from
student a
join score b on a.s_id=b.s_id where b.c_id in(
select c_id from course where t_id =(
select t_id from teacher where t_name = '张三'));
查询没学过"张三"老师授课的同学的信息
select * from
student c
where c.s_id not in(
select a.s_id from student a join score b on a.s_id=b.s_id where b.c_id in(
select c_id from course where t_id =(
select t_id from teacher where t_name = '张三')));
查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息
SELECT DISTINCT a.*
from student a
JOIN score b on a.s_id = b.s_id
JOIN score c on a.s_id = c.s_id
where b.c_id = '01' and c.c_id = '02'
select a.* from
student a,score b,score c
where a.s_id = b.s_id and a.s_id = c.s_id and b.c_id='01' and c.c_id='02';
查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息
SELECT *
from student a
where a.s_id in (
SELECT s_id from score where c_id = '01'
)
and
a.s_id not in (
SELECT s_id from score where c_id = '02'
)
查询没有学全所有课程的同学的信息
SELECT student.*
from student
where s_id not in (
SELECT d.s_id
from student d
JOIN score a on d.s_id = a.s_id
JOIN score b on d.s_id = b.s_id
JOIN score c on d.s_id = c.s_id
where a.c_id = '01' and b.c_id = '02' and c.c_id = '03'
)
select * from Student where s_id not in
(select s_id from score GROUP BY s_id HAVING count(c_id) = 3)
查询至少有一门课与学号为"01"的同学所学相同的同学的信息
SELECT student.*
from student
where s_id in(
SELECT DISTINCT s_id
FROM score
where c_id in (
SELECT c_id
from score
where score.s_id = '01'
)
)
and s_id != '01'
select * from student where s_id in(
select distinct a.s_id from score a where a.c_id in(select a.c_id from score a where a.s_id='01')
);
查询和"01"号的同学学习的课程完全相同的其他同学的信息
SELECT student.*
from student
where s_id in (
SELECT s_id
FROM score
where c_id in (
SELECT c_id
from score
where score.s_id = '01'
)
and s_id !='01'
GROUP BY s_id
HAVING count(1)=(SELECT count(1) from score WHERE s_id = '01' )
)
查询没学过"张三"老师讲授的任一门课程的学生姓名
SELECT s_name
from student
where s_id not in (
SELECT s_id
FROM score
where c_id in(
SELECT c_id
from course
JOIN teacher on course.t_id = teacher.t_id
WHERE teacher.t_name like '张三'
)
)
查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
SELECT student.s_id,student.s_name,ROUND(AVG(score.s_score))
from student
LEFT JOIN score on student.s_id = score.s_id
WHERE student.s_id in(
SELECT score.s_id
from score
WHERE score.s_score<60
GROUP BY score.s_id
HAVING count(score.s_id)>=2
)
GROUP BY student.s_id,student.s_name
检索"01"课程分数小于60,按分数降序排列的学生信息
SELECT student.*,score.s_id,score.s_score
from student
LEFT JOIN score on student.s_id = score.s_id
where score.c_id='01' and score.s_score<60
ORDER BY score.s_score desc
按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
# 分数为null的不知道怎么处理成0分
select a.s_id,a.s_name,
(select s_score from score where a.s_id = score.s_id and c_id = 01 )as '语文',
(select s_score from Score where a.s_id = Score.s_id and c_id = 02 )as '数学',
(select s_score from Score where a.s_id = Score.s_id and c_id = 03 )as '英语',
round(avg(s_score),2) as avg_score
from student a
left join score on a.s_id = score.s_id
group by a.s_id
order by avg_score desc
查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
-- 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
SELECT score.c_id ,course.c_name,max(score.s_score) as '最高分',min(score.s_score) as '最低分',round(avg(score.s_score),2) as '平均分',
ROUND(100*(SUM(case when score.s_score>=60 then 1 else 0 end)/SUM(case when score.s_score then 1 else 0 end)),2) as '及格率',
ROUND(100*(SUM(case when score.s_score>=70 and score.s_score<80 then 1 else 0 end)/SUM(case when score.s_score then 1 else 0 end)),2) as '中等率',
ROUND(100*(SUM(case when score.s_score>=80 and score.s_score<90 then 1 else 0 end)/SUM(case when score.s_score then 1 else 0 end)),2) as '优良率',
ROUND(100*(SUM(case when score.s_score>=90 then 1 else 0 end)/SUM(case when score.s_score then 1 else 0 end)),2) as '优秀率'
from score
LEFT JOIN course on score.c_id = course.c_id
GROUP BY score.c_id
按各科成绩进行排序,并显示排名
SELECT
a.s_id,a.c_id,
@i:=@i+1 as '不保留排名',
@k:=(case when @score=a.s_score then @k else @i end) as '保留排名',
@score:=a.s_score as score
from
(
SELECT s_id,c_id,s_score
from score
where c_id = '01'
ORDER BY s_score desc
)a,
(select @k:=0,@i:=0,@score:=0)s
UNION
SELECT
a.s_id,a.c_id,
@i:=@i+1 as '不保留排名',
@k:=(case when @score=a.s_score then @k else @i end) as '保留排名',
@score:=a.s_score as score
from
(
SELECT s_id,c_id,s_score
from score
where c_id = '02'
ORDER BY s_score desc
)a,
(select @k:=0,@i:=0,@score:=0)s
UNION
SELECT
a.s_id,a.c_id,
@i:=@i+1 as '不保留排名',
@k:=(case when @score=a.s_score then @k else @i end) as '保留排名',
@score:=a.s_score as score
from
(
SELECT s_id,c_id,s_score
from score
where c_id = '03'
ORDER BY s_score desc
)a,
(select @k:=0,@i:=0,@score:=0)s
查询学生的总成绩并进行排名
select a.s_id,
@i:=@i+1 as i,
@k:=(case when @score=a.sum_score then @k else @i end) as rank,
@score:=a.sum_score as score
from (select s_id,SUM(s_score) as sum_score from score GROUP BY s_id ORDER BY sum_score DESC)a,
(select @k:=0,@i:=0,@score:=0)s
查询不同老师所教不同课程平均分从高到低显示
SELECT teacher.t_name,course.c_name,round(avg(score.s_score),2)
from course
LEFT JOIN teacher on course.t_id=teacher.t_id
LEFT JOIN score on course.c_id= score.c_id
GROUP BY teacher.t_id,course.c_id
ORDER BY round(avg(score.s_score),2) DESC
查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
# 如果两人成绩并列相同,之后学生的排名+2
SELECT student.*,b.c_id,b.score, rank
from (
SELECT a.s_id,a.c_id,
@i:=@i+1 as i,
@k_1:=(case when @score=a.s_score then @k else @i end) as rank,
@score_1:=a.s_score as score
from
(SELECT score.s_id,score.c_id,score.s_score from score WHERE score.c_id = '01' ORDER BY score.s_score desc )as a,
(select @k_1:=0,@i:=0,@score_1:=0)s
) b
LEFT JOIN student on b.s_id=student.s_id
WHERE b.i in (2,3)
UNION
SELECT student.*,b.c_id,b.score, b.rank
from (SELECT a.s_id,a.c_id,
@j:=@j+1 as j,
@k_2:=(case when @score_2=a.s_score then @k_2 else @j end) as rank,
@score_2:=a.s_score as score
from
(SELECT score.s_id,score.c_id,score.s_score from score WHERE score.c_id = '02' ORDER BY score.s_score desc )as a,
(select @k_2:=0,@j:=0,@score_2:=0)s
) b
LEFT JOIN student on b.s_id=student.s_id
WHERE b.rank in (2,3)
UNION
SELECT student.*,b.c_id,b.score, b.rank
from (
SELECT a.s_id,a.c_id,
@z:=@z+1 as z,
@k_3:=(case when @score_3=a.s_score then @k_3 else @z end)as rank,
@score_3:=a.s_score as score
from (SELECT score.s_id,score.c_id,score.s_score from score WHERE score.c_id = '03' ORDER BY score.s_score desc )as a,(select @k_3:=0,@z:=0,@score_3:=0)as s
) b
LEFT JOIN student on b.s_id=student.s_id
WHERE b.rank in (2,3);
# 如果两人成绩并列相同,之后学生的排名还是+1
select d.*,c.rank,c.s_score,c.c_id from (
select a.s_id,a.s_score,a.c_id,@i:=@i+1 as rank from score a,(select @i:=0)s where a.c_id='01' ORDER BY a.s_score desc
)c
left join student d on c.s_id=d.s_id
where rank BETWEEN 2 AND 3
UNION
select d.*,c.rank,c.s_score,c.c_id from (
select a.s_id,a.s_score,a.c_id,@j:=@j+1 as rank from score a,(select @j:=0)s where a.c_id='02' ORDER BY a.s_score desc
)c
left join student d on c.s_id=d.s_id
where rank BETWEEN 2 AND 3
UNION
select d.*,c.rank,c.s_score,c.c_id from (
select a.s_id,a.s_score,a.c_id,@k:=@k+1 as rank from score a,(select @k:=0)s where a.c_id='03' ORDER BY a.s_score desc
)c
left join student d on c.s_id=d.s_id
where rank BETWEEN 2 AND 3;
统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0]人数及所占百分比
SELECT score.c_id,course.c_name ,
sum((case WHEN score.s_score <=100 and score.s_score>85 THEN 1 else 0 end )) as '100-85人数',
ROUND(100*sum((case WHEN score.s_score <=100 and score.s_score>85 THEN 1 else 0 end )) /count(1),2) as '100-85百分比',
sum((case WHEN score.s_score <=85 and score.s_score>70 THEN 1 else 0 end )) as '85-70人数',
ROUND(100*sum((case WHEN score.s_score <=85 and score.s_score>70 THEN 1 else 0 end )) /count(1),2) as '85-70百分比',
sum((case WHEN score.s_score <=70 and score.s_score>60 THEN 1 else 0 end )) as '70-60人数',
ROUND(100*sum((case WHEN score.s_score <=70 and score.s_score>60 THEN 1 else 0 end )) /count(1),2) as '70-60百分比',
sum((case WHEN score.s_score <=60 and score.s_score>=0 THEN 1 else 0 end )) as '60-0人数',
ROUND(100*sum((case WHEN score.s_score <=60 and score.s_score>=0 THEN 1 else 0 end )) /count(1),2) as '60-0百分比'
from score
LEFT JOIN course on score.c_id = course.c_id
GROUP BY score.c_id
查询学生平均成绩及其名次
SELECT a.s_id,
@i:=@i+1 as i,
@k:=(case when @avg_score=a.avg_s THEN @k ELSE @i end)as rank,
@avg_score:=a.avg_s as avg_score
from (
SELECT score.s_id,ROUND(AVG(score.s_score),2) as avg_s
from score
GROUP BY score.s_id
ORDER BY avg_s desc
) a,(SELECT @i:=0,@k:=0,@avg_score:=0)s
查询各科成绩前三名的记录
SELECT *
from(
SELECT a.s_id ,a.c_id,a.s_score,
@i:=@i+1 as rank
from (
SELECT s_id,c_id,s_score
from score
where c_id='01'
ORDER BY s_score desc
)a,
(SELECT @i:=0)s
)b
WHERE b.rank in (1,2,3)
UNION
SELECT *
from(
SELECT a.s_id ,a.c_id,a.s_score,
@j:=@j+1 as rank
from (
SELECT s_id,c_id,s_score
from score
where c_id='02'
ORDER BY s_score desc
)a,
(SELECT @j:=0)s
)b
WHERE b.rank in (1,2,3)
union
SELECT *
from(
SELECT a.s_id ,a.c_id,a.s_score,
@z:=@z+1 as rank
from (
SELECT s_id,c_id,s_score
from score
where c_id='03'
ORDER BY s_score desc
)a,
(SELECT @z:=0)s
)b
WHERE b.rank in (1,2,3)
查询每门课程被选修的学生数
SELECT course.c_id,count(score.s_id)
FROM course
LEFT JOIN score on course.c_id = score.c_id
GROUP BY course.c_id
查询出只有两门课程的全部学生的学号和姓名
SELECT student.s_id,student.s_name,count(1)
from score
LEFT JOIN student on score.s_id = student.s_id
GROUP BY student.s_id
HAVING count(1)=2
查询男生、女生人数
SELECT s_sex,count(1)
from student
GROUP BY s_sex
查询名字中含有"风"字的学生信息
SELECT *
from student
where s_name like '%风%'
查询同名同性学生名单,并统计同名人数
SELECT s_name,s_sex ,count(1)
from student
GROUP BY s_name ,s_sex
HAVING count(1)>1
查询1990年出生的学生名单
SELECT s_name
from student
where s_brith like '1990%'
查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
SELECT c_id,ROUND(AVG(s_score),2)
from score
GROUP BY c_id
ORDER BY ROUND(AVG(s_score),2) desc,c_id ASC
查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩
SELECT score.s_id ,student.s_name ,ROUND(AVG(score.s_score),2)
from score
LEFT JOIN student on score.s_id = student.s_id
GROUP BY score.s_id
HAVING ROUND(AVG(score.s_score),2)>=85
查询课程名称为"数学",且分数低于60的学生姓名和分数
SELECT student.s_name,score.s_score
from score
LEFT JOIN course on score.c_id = course.c_id
LEFT JOIN student on score.s_id = student.s_id
where course.c_name like '数学' and score.s_score < 60
查询所有学生的课程及分数情况;
select a.s_id,a.s_name,
SUM(case c.c_name when '语文' then b.s_score else 0 end) as '语文',
SUM(case c.c_name when '数学' then b.s_score else 0 end) as '数学',
SUM(case c.c_name when '英语' then b.s_score else 0 end) as '英语',
SUM(b.s_score) as '总分'
from student a
left join score b on a.s_id = b.s_id
left join course c on b.c_id = c.c_id
GROUP BY a.s_id,a.s_name
查询任何一门课程成绩在70分以上的姓名、课程名称和分数;
SELECT student.s_name,course.c_name,score.s_score
from score
LEFT JOIN student on score.s_id=student.s_id
LEFT JOIN course on score.c_id = course.c_id
where score.s_score > 70
查询不及格的课程及学生
SELECT student.s_id ,student.s_name,course.c_name,score.s_score
from score
LEFT JOIN student on score.s_id=student.s_id
LEFT JOIN course on score.c_id = course.c_id
where score.s_score <60
查询课程编号为01且课程成绩在80分以上的学生的学号和姓名;
SELECT student.s_id ,student.s_name
from score
LEFT JOIN student on score.s_id=student.s_id
where score.c_id = '01' and score.s_score>80
求每门课程的学生人数
SELECT score.c_id,count(2)
from score
GROUP BY c_id
查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩
SELECT student.*,score.s_score
from score
LEFT JOIN student on score.s_id = student.s_id
WHERE score.s_score in (
SELECT MAX(s_score) from score where score.c_id in (
SELECT c_id from course where t_id in (
SELECT t_id FROM teacher where teacher.t_name = '张三')
)
)
查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
SELECT DISTINCT a.s_id,a.c_id,a.s_score
from score a
LEFT JOIN score b on a.s_id=b.s_id
WHERE a.s_score=b.s_score and a.c_id != b.c_id
查询每门功成绩最好的前两名
select a.s_id,a.c_id,a.s_score
from score a
where
(select COUNT(1)
from score b
where b.c_id=a.c_id and b.s_score>=a.s_score
)<=2
ORDER BY a.c_id
统计每门课程的学生选修人数(超过5人的课程才统计)。
-- 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
SELECT c_id,count(1)
from score
GROUP BY c_id
HAVING count(1)>5
ORDER BY count(1) DESC ,c_id ASC
查询选修了全部课程的学生信息
SELECT *
from student
where s_id in(
SELECT s_id from score GROUP BY s_id HAVING count(1)=3
)
查询各学生的年龄
-- 按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
select s_id ,s_brith,
(DATE_FORMAT(NOW(),'%Y')-DATE_FORMAT(s_brith,'%Y') - (case when DATE_FORMAT(NOW(),'%m%d')>DATE_FORMAT(s_brith,'%m%d') then 0 else 1 END) )as age
from student;
查询本周过生日的学生
select *,WEEK(s_brith) from student
where WEEK(DATE_FORMAT(NOW(),'%Y%m%d'))=WEEK(s_brith)
查询下周过生日的学生
select * from student
where WEEK(DATE_FORMAT(NOW(),'%Y%m%d'))+1=WEEK(s_brith)
查询本月过生日的学生
select *
from student
where MONTH(DATE_FORMAT(NOW(),'%Y%m%d')) =MONTH(s_brith)
查询下月过生日的学生
select * from student where MONTH(DATE_FORMAT(NOW(),'%Y%m%d'))+1 =MONTH(s_brith)
本文来自博客园,作者:是小鱼呀,转载请注明原文链接:https://www.cnblogs.com/sophia12138/p/16870567.html