一、多表查询——建立基础表
----------------------------------------------'建表'----------------------------------------------create table dep(id int primary key auto_increment,name varchar(20));create table emp(id int primary key auto_increment,name varchar(20),sex enum('male','female') not null default 'male',age int,dep_id int);#插入数据insert into dep values(200,'技术'),(201,'人力资源'),(202,'销售'),(203,'运营'),(205,"安保部");insert into emp(name,sex,age,dep_id) values('yly','male',18,200),('zpx','female',48,201),('aaa','male',18,201),('bbb','male',28,202),('ccc','male',18,203),('ddd','female',18,204);----------------------------------------------'表结构'----------------------------------------------mysql> select * from dep;+-----+--------------+| id | name |+-----+--------------+| 200 | 技术 || 201 | 人力资源 || 202 | 销售 || 203 | 运营 || 205 | 安保部 |+-----+--------------+mysql> select * from emp;+----+-------+--------+------+--------+| id | name | sex | age | dep_id |+----+-------+--------+------+--------+| 1 | yly | male | 18 | 200 || 2 | zpx | female | 48 | 201 || 3 | aaa | male | 18 | 201 || 4 | bbb | male | 28 | 202 || 5 | ccc | male | 18 | 203 || 6 | ddd | female | 18 | 204 |+----+-------+--------+------+--------+
二、多表查询——连表操作
1、前戏
要多表查询,可以合并两张表,从而查询对应的数据案例一、查询每个人的姓名以及所处部门名称方法一、"不合理"# 笛卡尔积select * from emp,dep;mysql> select * from emp,dep;+----+------+--------+------+--------+-----+--------------+| id | name | sex | age | dep_id | id | name |+----+------+--------+------+--------+-----+--------------+| 1 | yly | male | 18 | 200 | 200 | 技术 || 1 | yly | male | 18 | 200 | 201 | 人力资源 || 1 | yly | male | 18 | 200 | 202 | 销售 || 1 | yly | male | 18 | 200 | 203 | 运营 || 1 | yly | male | 18 | 200 | 205 | 安保部 || 2 | zpx | female | 48 | 201 | 200 | 技术 || 2 | zpx | female | 48 | 201 | 201 | 人力资源 || 2 | zpx | female | 48 | 201 | 202 | 销售 || 2 | zpx | female | 48 | 201 | 203 | 运营 || 2 | zpx | female | 48 | 201 | 205 | 安保部 |... # 只显示查询出来的部分表# 合并成了,但是却查到了每个emp的id和部门的id重复一一对应,没有达到emp.dep_id和dep.id进行对应方法二、"不合理,会报错"mysql> select * from emp,dep where dep_id=id;ERROR 1052 (23000): Column 'id' in where clause is ambiguous#报错:where子句中的列“id”不明确,"""涉及到多表操作的时候 为了避免表字段重复需要在字段名的前面加上表名限制"""方法三、"合并表之后,id来源于哪个表很明确,查询得出"mysql> select emp.name,dep.name from emp,dep where emp.dep_id=dep.id;+------+--------------+| name | name |+------+--------------+| yly | 技术 || zpx | 人力资源 || aaa | 人力资源 || bbb | 销售 || ccc | 运营 |+------+--------------+
# 1、上述操作并不是合理的连表操作,效率低,太麻烦# 2、在mysql中,不用上述操作,而是使用mysql给我们几个关键字进行连表操作。
2、连表关键字
将两张表进行联合时,就可以使用下列四个关键字inner join 内连接:只连接两表中都存在(有对应关系)的数据select * from emp inner join dep on emp.dep_id = dep.id;left join 左连接:以左表为基准展示左表所有的数据没有对应则NULL填充select * from emp left join dep on emp.dep_id = dep.id;right join 右连接:以右表为基准展示右表所有的数据没有对应则NULL填充select * from emp right join dep on emp.dep_id = dep.id;union 全连接:展示左右两表中所有的数据没有对应则NULL填充select * from emp left join dep on emp.dep_id = dep.idunionselect * from emp right join dep on emp.dep_id = dep.id;"""注意左右连接的时候,以基准的时候,显示的顺序"""
三、多表查询——子查询
# 子查询:其实就是分布操作将一张表的查询结果当做另外一条SQL语句的查询条件案例一:查询 部门是技术或者人力资源的员工信息1.先查询技术和人力资源的部门编号select id from dep where name in ("技术","人力资源");2.根据部门标号去员工表中筛选出对应的员工数据select * from emp where dep_id in (200,201);3.汇总上两步得出答案:select * from emp where dep_id in (select id from dep where name in ("技术","人力资源"));
四、多表查询——练习题
1、练习的基础表
Navicat导入下面的文件
2、基于上表的练习题(必会)
1、 查询所有的课程的名称以及对应的任课老师姓名2、 查询平均成绩大于八十分的同学的姓名和平均成绩3、 查询没有报李平老师课的学生姓名4、 查询没有同时选修物理课程和体育课程的学生姓名5、 查询挂科超过两门(包括两门)的学生姓名和班级
解答过程:
1、 查询所有的课程的名称以及对应的任课老师姓名select cname,tname from course INNER JOIN teacher on course.teacher_id=teacher.tid;-------------------------------------------------------------------------------------2、 查询平均成绩大于八十分的同学的姓名和平均成绩select student_id,AVG(num) from score group by student_id having AVG(num)>80;-------------------------------------------------------------------------------------3、 查询没有报李平老师课的学生姓名第一步:查李平老师不教哪些课的course.cid号-- select course.cid from course INNER JOIN teacher on course.teacher_id=teacher.tid where tname not in ("李平老师");第二步:将student_id分组,里面包含上面的course.cid,并去重-- SELECT distinct student_id from score where course_id in (select course.cid from course INNER JOIN teacher on course.teacher_id=teacher.tid where tname not in ("李平老师"));第三步:将student.sid和刚刚表的student_id对应上SELECTsnameFROMstudentWHEREstudent.sid IN (SELECT DISTINCTstudent_idFROMscoreWHEREcourse_id IN (SELECTcourse.cidFROMcourseINNER JOIN teacher ON course.teacher_id = teacher.tidWHEREtname NOT IN ( "李平老师" )));-------------------------------------------------------------------------------------4、 查询没有同时选修物理课程和体育课程的学生姓名第一步:score表和course表-- select * from score INNER JOIN course on score.course_id=course.cid;第二步:筛选同事选物理以及体育的-- select student_id from (select * from score INNER JOIN course on score.course_id=course.cid) as t1 GROUP BY student_id HAVING n1 ;select student_id,GROUP_CONCAT(cname) from score INNER JOIN course on score.course_id=course.cid GROUP BY student_id having GROUP_CONCAT(cname) like "%物理%体育%" or GROUP_CONCAT(cname) like "%体育%物理%";第三步:not inselect * from student where student.sid not in (select student_id from score INNER JOIN course on score.course_id=course.cid GROUP BY student_id having GROUP_CONCAT(cname) like "%物理%体育%" or GROUP_CONCAT(cname) like "%体育%物理%");-------------------------------------------------------------------------------------5、 查询挂科超过两门(包括两门)的学生姓名和班级第一步:score.student_id分组,统计挂科大于等于2的-- select score.student_id from score where num <60 group by score.student_id having count(num) >=2;第二步:将class和student连表select student.sname,class.caption from class INNER JOIN student on class.cid=student.class_id where sid in (select score.student_id from score where num <60 group by score.student_id having count(num) >=2);
3、基于上表拓展的练习题(不一定要做)
2、查询学生表中男女生各有多少人select gender,count(gender) from student GROUP BY gender;3、查询物理成绩等于100的学生的姓名select sname from student where sid in (SELECT student_id from score INNER JOIN course on score.course_id=course.cid where num=100 and cname in ("物理"));5、查询所有学生的学号,姓名,选课数,总成绩 # group by可以将一一对应关系的两个字段一起分组select student.sid,student.sname,COUNT(course_id) as "选课数",sum(num) as "总成绩" from student INNER JOIN score on student.sid=score.student_id GROUP BY student.sid,student.sname;6、 查询姓李老师的个数select COUNT(tid) as "姓李的老师个数" from teacher where tname like "李%";8、 查询物理课程比生物课程高的学生的学号 #分为物理表和生物表SELECT t1.student_id from (select student_id,num as "生物成绩" from score INNER JOIN course on score.course_id=course.cid where cname in ("生物")) as t1 INNER JOIN (select student_id,num as "物理成绩" from score INNER JOIN course on score.course_id=course.cid where cname in ("物理")) as t2 on t1.student_id=t2.student_id where "生物成绩" < "物理成绩";-------------------------------------------------------------------------------------11、查询选修了所有课程的学生姓名-- 1、找出有几门课程course-- select COUNT(cid) from course;-- 2、score表以student_id分组,计数course_id in 上面查出来的表格4-- select student_id from score GROUP BY student_id having count(course_id) in (select COUNT(cid) from course);-- 3、找出student.sid in student_idselect student.sname from student where student.sid in (select student_id from score GROUP BY student_id having count(course_id) in (select COUNT(cid) from course));-------------------------------------------------------------------------------------12、查询李平老师教的课程的所有成绩记录-------------------------------------------------------------------------------------13、查询全部学生都选修了的课程号和课程名-------------------------------------------------------------------------------------14、查询每门课程被选修的次数-------------------------------------------------------------------------------------15、查询之选修了一门课程的学生姓名和学号-------------------------------------------------------------------------------------16、查询所有学生考出的成绩并按从高到低排序(成绩去重)-------------------------------------------------------------------------------------17、查询平均成绩大于85的学生姓名和平均成绩-------------------------------------------------------------------------------------18、查询生物成绩不及格的学生姓名和对应生物分数-------------------------------------------------------------------------------------19、查询在所有选修了李平老师课程的学生中,这些课程(李平老师的课程,不是所有课程)平均成绩最高的学生姓名-------------------------------------------------------------------------------------20、查询每门课程成绩最好的前两名学生姓名-------------------------------------------------------------------------------------21、查询不同课程但成绩相同的学号,课程号,成绩-------------------------------------------------------------------------------------22、查询没学过“叶平”老师课程的学生姓名以及选修的课程名称;-------------------------------------------------------------------------------------23、查询所有选修了学号为1的同学选修过的一门或者多门课程的同学学号和姓名;-------------------------------------------------------------------------------------24、任课最多的老师中学生单科成绩最高的学生姓名
