一、建表语句
# 学生表
CREATE TABLE `student` (
`id` varchar(20) NOT NULL COMMENT '学生编号',
`name` varchar(20) NOT NULL DEFAULT '' COMMENT '学生姓名',
`birth` varchar(20) NOT NULL DEFAULT '' COMMENT '出生年月',
`sex` varchar(10) NOT NULL DEFAULT '' COMMENT '学生性别',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
# 课程表
CREATE TABLE `course` (
`id` varchar(20) NOT NULL COMMENT '课程编号',
`name` varchar(20) NOT NULL DEFAULT '' COMMENT '课程名称',
`teacher_id` varchar(20) NOT NULL COMMENT '教师编号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
# 教师表
CREATE TABLE `teacher` (
`id` varchar(20) NOT NULL COMMENT '教师编号',
`name` varchar(20) NOT NULL DEFAULT '' COMMENT '教师姓名',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
# 成绩表
CREATE TABLE `score` (
`student_id` varchar(20) NOT NULL COMMENT '学生编号',
`course_id` varchar(20) NOT NULL COMMENT '课程编号',
`score` int(3) DEFAULT NULL COMMENT '分数',
PRIMARY KEY (`student_id`,`course_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
二、测试数据
--插入学生表测试数据
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 student.* , score.score AS 01_score,s.score AS 02_score
FROM student
JOIN score ON student.id = score.student_id AND score.course_id = '01'
LEFT JOIN score s ON student.id =s.student_id AND s.course_id = '02' OR s.score =NULL
WHERE score.score >s.score;
# 方式2
SELECT student.* , score.score AS 01_score , s.score AS 02_score
FROM student , score , score s
WHERE student.id = score.student_id AND student.id = s.student_id
AND score.course_id = '01' AND s.course_id = '02' AND score.score > s.score ;
2、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩
SELECT student.id , student.`name` , ROUND(AVG(score.score),2) AS avg_score
FROM student
JOIN score ON student.id = score.student_id
GROUP BY student.id HAVING avg_score > 60;
3、查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩(包括有成绩的和无成绩的)
SELECT student.id , student.`name` , ROUND(AVG(score.score),2) AS avg_score
FROM student
JOIN score ON student.id = score.student_id
GROUP BY student.id HAVING avg_score < 60
UNION
SELECT student.id , student.`name` , 0 AS avg_score
FROM student
WHERE student.id NOT IN (SELECT DISTINCT student_id FROM score);
4、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
SELECT student.id , student.`name` , COUNT(score.course_id) AS sum_course , SUM(score.score) AS sum_score
FROM student
LEFT JOIN score ON student.id = score.student_id
GROUP BY student.id ;
5、查询"李"姓老师的数量
SELECT COUNT(teacher.id)
FROM teacher
WHERE teacher.`name` LIKE '李%';
6、查询学过"张三"老师授课的同学的信息
# 方式1
SELECT student.*
FROM student , course , score , teacher
WHERE student.id = score.student_id AND course.id = score.course_id AND course.teacher_id = teacher.id AND teacher.`name` = '张三';
# 方式2
SELECT student.*
FROM student
JOIN score ON student.id = score.student_id
JOIN course ON score.course_id = course.id
JOIN teacher ON course.teacher_id = teacher.id
WHERE teacher.`name` = '张三';
# 方式3
SELECT student.*
FROM student
JOIN score ON student.id = score.student_id
WHERE score.course_id IN (SELECT course.id
FROM course
WHERE course.teacher_id = (SELECT teacher.id
FROM teacher
WHERE teacher.`name` = '张三'));
7、查询没学过"张三"老师授课的同学的信息
SELECT student.*
FROM student
WHERE student.id NOT IN (
SELECT student.id
FROM student
JOIN score ON student.id = score.student_id
JOIN course ON score.course_id = course.id
JOIN teacher ON course.teacher_id = teacher.id
WHERE teacher.`name` = '张三'
);
8、询学过编号为"01"并且也学过编号为"02"的课程的同学的信息
SELECT student.*
FROM student , score s1, score s2
WHERE student.id = s1.student_id AND student.id = s2.student_id AND s1.course_id = '01' AND s2.course_id = '02';
9、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息
# 方式1
SELECT student.*
FROM student
JOIN score ON student.id = score.student_id AND score.course_id = '01'
WHERE student.id NOT IN (
SELECT student.id
FROM student
JOIN score ON student.id = score.student_id AND score.course_id = '02'
)
# 方式2
SELECT student.*
FROM student
WHERE student.id in (
SELECT score.student_id
FROM score
WHERE score.course_id = '01'
) AND student.id NOT IN (
SELECT score.student_id
FROM score
WHERE score.course_id = '02'
)
10、查询没有学全所有课程的同学的信息
# 方法1
SELECT student.*
FROM student
LEFT JOIN score ON student.id = score.student_id
GROUP BY student.id
HAVING count(student.id) < (
SELECT count(course.id)
FROM course
)
# 方式2
SELECT student.*
FROM student
WHERE student.id NOT IN (
SELECT score.student_id
FROM score
GROUP BY score.student_id
HAVING count(score.student_id) = (
SELECT count(course.id)
FROM course
)
)
11、查询至少有一门课与学号为"01"的同学所学相同的同学的信息
SELECT student.*
FROM student
WHERE student.id IN(
SELECT score.student_id
FROM score
WHERE score.course_id IN (
SELECT score.course_id
FROM score
WHERE score.student_id = '01'
)
)
12、查询和"01"号的同学学习的课程完全相同的其他同学的信息
# 方式1
SELECT student.*
FROM student
WHERE student.id in (
SELECT score.student_id
FROM score
GROUP BY score.student_id
HAVING count(score.student_id) = (
SELECT count(score.student_id)
FROM score
WHERE score.student_id = '01'
)
) AND student.id NOT IN (
#找到‘01’同学没学过课程的同学
SELECT score.student_id
FROM score
WHERE score.course_id in (
#找到‘01’同学没学过的课程
SELECT course.id
FROM course
WHERE course.id NOT IN (
#找出‘01’同学学习的课程
SELECT score.course_id
FROM score
WHERE score.student_id = '01'
)
)
) AND student.id NOT IN ('01');
# 方式2
SELECT student.*
FROM (
SELECT score.student_id , GROUP_CONCAT(score.course_id ORDER BY score.course_id) group1
FROM score
GROUP BY score.student_id
HAVING score.student_id > '01'
) s1
JOIN (
SELECT score.student_id , GROUP_CONCAT(score.course_id ORDER BY score.course_id) group2
FROM score
GROUP BY score.student_id
HAVING score.student_id = '01'
) s2 ON s1.group1 = s2.group2
JOIN student ON student.id = s1.student_id;
13、查询没学过"张三"老师讲授的任一门课程的学生姓名
SELECT student.`name`
FROM student
WHERE student.id NOT IN (
SELECT score.student_id
FROM score
WHERE score.course_id IN (
SELECT course.id
FROM course , teacher
WHERE course.teacher_id = teacher.id AND teacher.`name` = '张三'
)
)
14、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
# 方式1
SELECT student.id , student.`name` , s1.avg_score
FROM student
JOIN (
SELECT score.student_id , ROUND(AVG(score.score),2) AS avg_score
FROM score
WHERE score.score < 60
GROUP BY score.student_id
HAVING COUNT(*) >=2
) AS s1 ON student.id = s1.student_id;
# 方式2
SELECT student.id , student.`name` , ROUND(AVG(score.score),2) AS avg_score
FROM student
LEFT JOIN score ON student.id = score.student_id
WHERE student.id in (
SELECT score.student_id
FROM score
WHERE score.score < 60
GROUP BY score.student_id
HAVING COUNT(*) >= 2
)
GROUP BY student.id;
15、检索"01"课程分数小于60,按分数降序排列的学生信息
SELECT student.* , score.course_id , score.score
FROM student
LEFT JOIN score ON student.id = score.student_id
WHERE score.course_id = '01' AND score.score < 60
ORDER BY score.score DESC;
16、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩