MySQL数据库

一、多表练习题

"""
编写复杂的SQL不要想着一口气写完
	一定要先明确思路 然后一步步写一步步查一步步补
"""
1、查询所有的课程的名称以及对应的任课老师姓名
4、查询平均成绩大于八十分的同学的姓名和平均成绩
7、查询没有报李平老师课的学生姓名
8、查询没有同时选修物理课程和体育课程的学生姓名
9、查询挂科超过两门(包括两门)的学生姓名和班级

第一题

1、查询所有的课程的名称以及对应的任课老师姓名

# 解题思路
    # 涉及表格:课程表、讲师表
    # 1、查看课程及讲师表数据
    -- SELECT * FROM course;
    -- select * from teacher;
    # 2、以课程表为主表,拼接课程与讲师表
    SELECT
        course.cname,
        teacher.tname 
    FROM
        course
        LEFT JOIN teacher ON course.teacher_id = tid;

第二题

2、查询平均成绩大于八十分的同学的姓名和平均成绩

# 解题思路
# 涉及表格:成绩表(score)、学生表(student)
# 1、以学生标号为准,进行分组,同时获取学生平均成绩进行赛选
-- select student_id,avg(num) as num from score GROUP BY student_id HAVING avg(num)>=80;
# 2、分析结果需要用到两张表,采用拼表
SELECT
	student.sname,
	t1.num 
FROM
	student
	INNER JOIN ( SELECT student_id, avg( num ) AS num FROM score GROUP BY student_id HAVING avg( num )>= 80 ) AS t1 ON student.class_id = t1.student_id;

第三题:

3、查询没有报李平老师课的学生姓名

# 解题思路:
# 涉及表格:讲师表、学生表、课程表、分数表
# 1、先获取到李平老师的编号
-- select tid from teacher where teacher.tname='李平老师';
# 2、获取到李平老师所教授的课程编号
-- select course.cid from course where course.teacher_id = (select tid from teacher where teacher.tname='李平老师');
# 3、通过课程编号获取分数表里没有报李平老师课程的学生编号 2、4
-- SELECT DISTINCT student_id FROM score where course_id IN ( select cid from course where teacher_id = (select tid from teacher where teacher.tname='李平老师'));

# 通过学生编号,获取学生姓名并去重
SELECT DISTINCT
	student.sname 
FROM
	student 
WHERE
	student.sid not IN (
	SELECT
		score.student_id 
	FROM
		score 
	WHERE
		score.course_id IN (
		SELECT
			course.cid 
		FROM
			course 
	WHERE
	course.teacher_id = ( SELECT tid FROM teacher WHERE teacher.tname = '李平老师' )));

第四题

-- 8、查询没有同时选修物理课程和体育课程的学生姓名(报了两门或者一门不报的都不算)
# 1.先确定需要的表  学生表 分数表 课程表
# 2.预览表数据
# 3.根据给出的条件确定起手的表
# 4.根据物理和体育筛选课程id
-- select cid from course where cname in ('物理','体育');
# 5.根据课程id筛选出所有跟物理 体育相关的学生id
-- select * from score where course_id in (select cid from course where cname in ('物理','体育'))
# 6.统计每个学生报了的课程数 筛选出等于1的
-- select student_id from score where course_id in (select cid from course where cname in ('物理','体育'))
-- group by student_id
-- having count(course_id) = 1;
# 7.子查询获取学生姓名即可
-- SELECT
-- 	sname
-- FROM
-- 	student
-- WHERE
-- 	sid IN (
-- 		SELECT
-- 			student_id
-- 		FROM
-- 			score
-- 		WHERE
-- 			course_id IN (
-- 				SELECT
-- 					cid
-- 				FROM
-- 					course
-- 				WHERE
-- 					cname IN ('物理', '体育')
-- 			)
-- 		GROUP BY
-- 			student_id
-- 		HAVING
-- 			count(course_id) = 1
-- 	)

第五题

-- 9、查询挂科超过两门(包括两门)的学生姓名和班级
# 1.先确定涉及到的表	分数表 学生表 班级表
# 2.预览表数据
-- select * from class
# 3.根据条件确定以分数表作为起手条件
# 步骤1 先筛选掉大于60的数据
-- select * from score where num < 60;
# 步骤2 统计每个学生挂科的次数
-- select student_id,count(course_id) from score where num < 60 group by student_id;
# 步骤3 筛选次数大于等于2的数据
-- select student_id from score where num < 60 group by student_id having count(course_id) >= 2;
# 步骤4 连接班级表与学生表 然后基于学生id筛选即可
SELECT
	student.sname,
	class.caption
FROM
	student
INNER JOIN class ON student.class_id = class.cid
WHERE
	student.sid IN (
		SELECT
			student_id
		FROM
			score
		WHERE
			num < 60
		GROUP BY
			student_id
		HAVING
			count(course_id) >= 2
	);