多表联查可以通过连接运算实现,即将多张表通过主外键关系关联在一起进行查询

一、内联查询

1.非等值查询(也被称为笛卡尔积)

语法:select 查询的字段 from 表1,表2 ........

以我们常见的学生表、成绩表、课程表、老师表、班级表为例(下同)

select * from student,sc,course,teacher,class;

查询学生表、成绩表、课程表、老师表、班级表所有数据

非等值查询会将所有数据以乘积的形式展示出来,所以会产生大量重复数据

1.等值查询

语法:select 查询的字段 from 表1,表2 where 条件1,条件2...

select * from student,sc where sc.sid = student.sid;

查询学生表和成绩表的所有数据

2.inner join

语法:select 查询的字段 from 表1 inner join 表2 on 条件

select * from student inner join sc on sc.sid = student.sid;

也可以拿到学生表和成绩表的所有数据

如果我们想要拿到(1)班所有男同学数学科目的平均成绩

select avg(score) from student 
inner join sc on student.sid = sc.sid
inner join course on sc.cid = course.cid
inner join teacher on course.tid = teacher.tid 
inner join class on student.classid = class.classid
where student.ssex = '男' and student.classid = 1 and cname = '数学';

二、外联查询

注意:在使用外联查询时一定要分清楚哪张表是主表

1.left join(左外联查询)
语法:select 查询的字段 from 表1 left join 表2 on 条件
如果我们想查询没有班级的学生,可以将学生表作为主表来外联班级表
select * from student left join class on student.classid = class.classid where class.classid is null;

2.right join(右外联查询)

语法:select 查询的字段 from 表1 right join 表2 on 条件

如果我们想查询没有学生的班级,则可以将班级表作为主表来外联学生表
select * from class left join student on student.classid = class.classid where student.sid is null;

三、表的并集

union 求两个结果的并集

语法:select 查询的字段(表1的数据) from 表1
           union 
           select 查询的字段(表2的数据) from 表2

如果我们想查询所有学生和所有班级的信息
select * from student left join class on student.classid = class.classid 
union
select * from student right join class on student.classid = class.classid;
注意:
1.列名不一致时,会以第一张表的表头为准,并对其栏目。
2.会将重复的行过滤掉。
3.如果查询的表的列数量不相等时,会报错。
4.在每个子句中的排序是没有意义的,mysql在进行合并的时候会忽略掉。
5.如果子句中的排序和limit进行结合是有意义的。
6.可以对合并后的整表进行排序
union all 也是求两个结果的并集,与union的区别在于不会过滤重复的内容

四、子查询

1.where 型子查询

如果我们想要查询id数字最大的一个学生(使用排序+分页实现)

select * from student order by sid desc  limit 1;

使用where子查询

select * from student where sid = (select max(sid) from student);

2.from 型子查询

把内层的查询结果当成临时表,供外层 sql 再次查询,查询结果集可以当成表看待。
临时表要使用一个别名

如果我们想要查询大于5人的班级名称和人数(不使用子查询)

select classname,count(*) from class,student 
where  class.classid = student.classid
group by class.classid having count(*) > 5;

使用from子查询

select class.classname,t1.人数 from class inner join 
 (select classid,count(*) 人数 from student group by classid) t1
on class.classid = t1.classid
where t1.人数  > 5;

关于子查询的类型还有exists 型子查询和any,some,all 型子查询,这两种类型子查询一般不常用,所以这里不做过多赘述。

由此可见,子查询实际上是将多条查询语句以子父类的方式拼接起来,得到的结果和我们使用内外联查询或分组、排序等条件查询相同,但逻辑相对来说复杂些。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐