MySql多表关联语句操作

MySql多表关联语句操作

一、建表语句

# 学生表
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、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值