MySQL系列-DML语句之select多表连接查询
运维少年 运维少年
系列文章说明
MySQL系列文章包含了软件安装、具体使用、备份恢复等内容,主要用于记录个人的学习笔记,主要使用的MySQL版本为5.7.28,服务器系统版本为CentOS 7.5。本章节为select多表连接查询内容,本章节使用到了school数据库。
环境准备:
①创建数据库
CREATE DATABASE school CHARSET utf8mb4;
USE school;
②新建学生表
CREATE TABLE student(
sno INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '学号',
sname VARCHAR(20) NOT NULL COMMENT '姓名',
sage TINYINT UNSIGNED NOT NULL COMMENT '年龄',
ssex ENUM('f','m') NOT NULL DEFAULT 'm' COMMENT '性别'
)ENGINE=INNODB CHARSET utf8mb4;
③新建教师表
CREATE TABLE teacher(
tno INT NOT NULL PRIMARY KEY COMMENT '教师编号',
tname VARCHAR(20) NOT NULL COMMENT '教师名字'
)ENGINE=INNODB CHARSET utf8mb4;
④新建课程表
CREATE TABLE course(
cno INT NOT NULL PRIMARY KEY COMMENT '课程编号',
cname VARCHAR(20) NOT NULL COMMENT '课程名称',
tno INT NOT NULL COMMENT '教师编号'
)ENGINE=INNODB CHARSET utf8mb4;
⑤新建成绩表
CREATE TABLE sc(
sno INT NOT NULL COMMENT '学号',
cno INT NOT NULL COMMENT '课程标号',
score INT NOT NULL DEFAULT 0 COMMENT '成绩'
)ENGINE=INNODB CHARSET utf8mb4;
⑥插入数据
INSERT INTO student(sno,sname,sage,ssex) VALUES(1,'zhang3',18,'m'),
(2,'zhang4',18,'m'),
(3,'li4',18,'m'),
(4,'wang5',19,'f'),
(5,'zh4',18,'m'),
(6,'zhao4',18,'m'),
(7,'ma6',19,'f'),
(8,'yunwei',20,'m'),
(9,'arp',20,'f'),
(10,'oldp',25,'m');
INSERT INTO teacher(tno,tname) VALUES(101,'hansir'),(102,'yanhui'),(103,'hongca');
INSERT INTO course(cno,cname,tno) VALUES(1001,'linux',101),(1002,'python',102),(1003,'mysql',103);
INSERT INTO sc(sno,cno,score) VALUES
(1,1001,80),
(1,1002,59),
(2,1002,90),
(2,1003,100),
(3,1001,99),
(3,1003,40),
(4,1001,79),
(4,1002,61),
(4,1003,99),
(5,1003,40),
(6,1001,89),
(6,1003,77),
(7,1001,67),
(7,1003,82),
(8,1001,70),
(9,1003,80),
(10,1003,96);
多表连接查询
多表连接 为什么需要多表连接?
我们查询的需求,需要的数据,可能来自于多张表,单张表无法满足
格式:
select 列1,列2... from 表1 join 表2... on 条件;
多表连接 笛卡尔乘积
何为笛卡尔乘积?
例如,A={a,b}, B={0,1,2},则
A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}
B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}
最简单的多表连接:
select * from teacher,course;
多表连接 内连接
内连接是多表连接中使用最广泛也是最简单的连接查询,内连接及多表的交集部分。
select * from teacher join course on teacher.tno=course.tno;
多表连接 外连接
左连接(left join):左表所有的数据+右表满足条件的数据
select * from course left join teacher on teacher.tno=course.tno;
右连接:右表所有的数据+左表满足条件的数据
select * from course right join teacher on teacher.tno=course.tno;
多表连接 实战
①查询zhang3学习了几门课程
select sname,count(sc.sno) from student join sc on student.sno=sc.sno and student.sname='zhang3' group by sc.sno;
②查询zhang3学习的课程名称有哪些
select student.sno,student.sname,group_concat(course.cname) from student join sc on student.sno=sc.sno join course on sc.cno=course.cno and student.sname='zhang3' group by student.sno;
③查询yanhui老师教的学生名
select teacher.tname,group_concat(student.sname) from student join sc on student.sno=sc.sno join course on sc.cno=course.cno join teacher on teacher.tno=course.tno where teacher.tname='yanhui' group by teacher.tno;
④查询yanhui所教课程的平均分数
select teacher.tname,avg(sc.score) from teacher join course on teacher.tno=course.tno join sc on sc.cno=course.cno where teacher.tname='yanhui' group by teacher.tno,course.cno;
⑤每位老师所教课程的平均分,并按照平均分排序
select teacher.tname,avg(sc.score) from teacher join course on teacher.tno=course.tno join sc on sc.cno=course.cno group by teacher.tno order by avg(sc.score);
⑥查询yanhui老师所教的不及格的学生
select teacher.tname,student.sname from teacher join course on teacher.tno=course.tno and teacher.tname='yanhui' join sc on sc.cno=course.cno and sc.score<60 join student on student.sno=sc.sno;
⑦查询所有老师所教学生不及格的信息
select teacher.tname,group_concat(student.sname) from teacher join course on teacher.tno=course.tno join sc on sc.cno=course.cno and sc.score<60 join student on student.sno=sc.sno group by teacher.tno;
⑧查询平均成绩大于60分的同学的学号和平均成绩
select student.sname,avg(sc.score) from student join sc on student.sno=sc.sno group by sc.sno having avg(sc.score)>60;
⑨查询所有同学的学号、姓名、选课数、总成绩
select student.sno,student.sname,count(sc.sno),sum(sc.score) from student join sc on student.sno=sc.sno group by sc.sno;
⑩查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
select sc.cno,min(sc.score),max(sc.score) from sc group by sc.cno;