Mysql联合查询

1.联合查询

定义及数据准备

实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积:
关于笛卡尔积通过一个例子理解:
如在a表中有a1,a2,a3,在b表中有b1,b2,b3等数据,因此笛卡尔积就为
a1b1,a1b2,a1b3
a2b1,a2b2,a2b3,
a3b1,a3b2,a3b3
表a中的所有数据都能跟表b的所有数据有所对应;
在这里插入图片描述
首先把准备好三张表和其对应的数据:
班级表
在这里插入图片描述
学生表:
在这里插入图片描述
课程表:
在这里插入图片描述
分数表:
在这里插入图片描述
在这里插入图片描述

2.内连接

通过两张表共有的列来筛选信息,达到尽快查询的目的
语法:
select 字段 from 表1 别名1 [inner] join 表2 别名2 on 链接条件 and 其他条件
select 字段 from 表1 别名1,表2 别名2 where 链接条件 and 其他条件

2.1 例子1:

查询许仙的成绩;
具体看看整个查询的过程;
首先直接进行学生表和分数表的链接查询:

select * from student inner join score;

在这里插入图片描述
以及
在这里插入图片描述
查询到的表中共有189行数据,每个人都对应了成绩表中的所有成绩,也就是说每个人有了21个成绩,所以9个学生有189条数据,与上述的笛卡尔积相互对应起来,
接下来要给查询加上条件:我们知道在score表中,有student_id和course_id,因此要从score表中筛选出sutdnet_id和student中的id相等的分数

select * from student inner join score on student.id=score.student_id;

在这里插入图片描述
此时,我们看到的表中,所有人的成绩和本人都对应起来,现在就可以去筛选出许仙了;

select * from student inner join score on student.id=score.student_id and student.id =4;

在这里插入图片描述
到这一步其实查询已经结束了,我们已经获得了许仙的各科成绩了,但是只有课程id不知道课程的名字
进行改进:

select stu.sn,stu.name,sco.score,cou.name from student stu inner join score sco on stu.id=sco.student_id
inner join course on score.course_id=course.id and student.id=4;

在这里插入图片描述
分析上述代码,要查询的是学生表中的学生sn和name,以及成绩表中的score,以及课程表中的name;
首先通过分数表中的学生id和学生表中的id对应查到当前每个学生的成绩,然后通过分数表中的课程id在课程表中查询相对应的课程名;
上述代码也可以不使用inner join来查询:

select stu.sn,stu.name,sco.score,cou.name as 课程名 from student stu,score sco,course cou
where stu.id=sco.student_id
and sco.course_id = cou.id
and stu.name='许仙';

在这里插入图片描述

2.2 查询所有学生的总成绩

重点关注查询的条件,首先stu.id=sco.student_id,此条件用于查询属于每个学生的对应成绩,

select stu.sn,stu.name,sum(score) from student stu,score sco where stu.id=sco.student_id;

在这里插入图片描述
这样子查询到的结果并没有将学生分开,而是查询到了单个学生的成绩,并且也不是单个学生的总成绩,而是将成绩表中的所有的成绩进行了加和,但是为什么只显示了李逵呢,去掉sum再试试

select stu.sn,stu.name,score from student stu,score sco where stu.id=sco.student_id;

在这里插入图片描述
由此可以看出,因为没有设置对单个学生的查询条件,显示结果将所有的score加和到了一起,并且只显示了第一个学生
对上述代码进行改进:加上分组将每个学生的成绩都分开;

select stu.sn,stu.name,sum(score) from student stu,score sco where stu.id=sco.student_id
group by stu.id

在这里插入图片描述

3.外连接

外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完全显示我们就说是右外连接。
首先是左连接,以左表为主表,显示左表中所有的内容,

select stu.id,stu.name,sco.score from student stu left join score sco on stu.id=sco.student_id group by stu.id;

在这里插入图片描述
右连接,以右表为主,显示右表中有的内容:

select stu.id,stu.name,sco.score from student stu right join score sco on stu.id=sco.student_id group by stu.id;

在这里插入图片描述
可以看出左链接中显示了左表也就是student表的全部内容而右链接,显示了右表score中的全部内容,null的内容不显示,如果不指定左右链接,就会显示两张表的交集都不为空的情况
在这里插入图片描述
再来看看如何区分左右表:

 select stu.id,stu.name,sco.score from score sco left join student stu  on stu.id=sco.student_id group by stu.id;

在这里插入图片描述
在from之后将score和student的位置进行了互换,可以看出当前结果以score表为主表,显示其所有内容,null的就不显示

4. 自连接

例子:查询所有计算机原理比java成绩高的分数信息
首先看看课程表中的信息:
在这里插入图片描述

可以看到:计算机原理的id=3;java的id=1;
因此我们需要在score表中去搜索id=3的成绩>id=1的成绩
需要进行自己与自己的内容进行对比,这种方式成为自链接
自链接的实现:
需要注意的是:我们在实现该次查询的时候,要注意学生的id需要相等,因为我们查询的是同一个学生的计算机原理比java成绩高的成绩信息

select s2.* from score s1,score s2
   where s1.student_id = s2.student_id  and s1.course_id=1 and s2.course_id=3 and s1.score<s2.score;

在这里插入图片描述
查询结果种只显示了计算机原理的成绩,这是由于我们联合查询中 select s2.*;条件中查询的是 s2.course_id=3的课程信息,
以上查询可以表示为,查询s1和s2表中,学生id相等的情况下;表1中的course_id=1和course_id=3且1的成绩小于3的成绩,并显示表二中信息,
其实就是在对比表1和表2中的信息,首先筛选出学生id相等的信息,然后筛选出表2中的courseid=3的成绩大于表1中coureseid=1的信息,并将其显示出来

5.子查询

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询
例子:查询许仙的同班同学;
首先得知道许仙在哪个班级;

select   *  from student where classes_id = (select classes_id from student stu where stu.name='许仙');

在这里插入图片描述
多行子查询:
查询语文或英文课程的成绩信息:
关键字IN和NOT IN
结合上述的嵌套做法,先得知道语文或英文的课程id

select * from score where course_id in(select id from course where name='语文' or name='英语');

在这里插入图片描述

6.合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。使用UNION和UNION ALL时,前后查询的结果集中,字段需要一致。
重点:查询的结果格式需要保持一致:

  • 查询id小于3,或者名字为“英文”的课程:

在这里插入图片描述

union all
该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。

  • 案例:查询id小于3,或者名字为“Java”的课程
    在这里插入图片描述
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值