【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)
posted @ 2022-11-08 17:39  是小鱼呀  阅读(80)  评论(0编辑  收藏  举报