MySQL中的多表连接查询

多表连接查询

导论
表连接的本质尽量减少数据冗余。例如创建学生表,老师表,课程表,选课表比只创建一个表更能减少数据冗余。这四张表可以通过主外键和引用的方式相互连接

数据库连接的本质:只有一种连接,叫做引用的关系

数据库的连接类型
连接(join):将一张表中的行按照某个条件(连接条件)和另一张表中的行连接起来形成一个新行的过程叫做连接

根据查询返回的结果,连接可以分为3大类:
内连接(inner join)
外连接(outer join)
交叉连接(cross join)

根据连接条件所使用的操作符,又可分为:
相等连接(使用等号操作符)
不等连接(不使用等号操作符)

限定列名
在连接查询中,一个列可能出现在多张表中。为了避免引起歧义,通常在列名前面加上表名或表别名作为前缀
使用表别名作为前缀,可以使得SQL代码较短,使用的内存更少
内连接(inner join)
只返回两张表中所有满足连接条件的行

如何从多表中取数据?
1.我们先确认我们需要取的数据来自于那些表
2.画出表的结构,找出这些表的的关联关系(例如:学生和选课通过学生ID关联起来)
3.写出select语句的大体结构
4.from后边跟上查询的数据来自哪些表(起别名相对方便)
5.where后边跟关联关系
6.可以对取出的数据进行进一步处理(使用and,order by , group by 等)

示例:select s.sname, t.tname, c.cname, x,xuefen ##展示s表的sname列,t表的tname列
c表的cname列,x表的xuefen列
from stu s, tea t, course c, xuanke x ##分别给stu表,tea表等起别名为s,t等

  where s.sid=x.sid and t.tid=x.tid and c.cid=x.cid  ##s表的sid列等于x表的sid列等
                                           中间用and连接
  and s.sname=’李三’;
  多表关联时,如果两个表中都有的列需要指定在那个表中,如果只在一个表中可以不用指定在在那个表

主外键

主键:学生表里的学号列就是该表的主键列,所谓主键列就是这一列的每一个值都能唯一的代表这一行的数据。主键列的值唯一,不能有重复,不能为空,主键列一般是数字列

外键:选课表里的学号列就是外键,外键列的所有数据来自于主表(学生表)对应的主键
外键的值一定来自于主键,外键一定引用主键

表连接的相关语法
1.使用on字句
示例:select s.sname, t.tname, c.cname, x,xuefen ##展示s表的sname列,t表的tname列c表的cname列,x表的xuefen列
from stu s ##给stu表起别名为 s stu是主表
join xuanke x ##加入xuanke表,别名是x
on s.sid=x.sid ##on加条件,条件是s表的sid列等于x表的sid列,往下类似
join tea t
on x.tid=t.tid
join course c
on c.cid=x.cid; ##注:最后的from有stu,xuanke,tea,course四张表在这里插入图片描述2.using字句
两个关联表的列名字相同时,可以使用using字句
示例:
select s.sname, t.tname, c.cname, x,xuefen
from stu s ##stu是主表
join xuanke x
using(sid) ##因为学生表和选课表中都有sid列,且该列是关联列,可以使用using 字句
join tea t
using(tid)
join course c
using(cid);在这里插入图片描述3.使用natural join字句
NATURAL JOIN子句自动到两张表中查找所有同名同类型的列拿来做连接列,进行相等连接
示例:
select s.sname, t.tname, c.cname, x,xuefen
from stu s
natural join xuanke x ##因为学生表和选课表中都有sid列,且该列是关联列,可以使用natural join字句,关联列进行自动连接
natural join tea t ##同理

natural join course c; #同理在这里插入图片描述注:推荐使用经典写法和on字句的写法!!

外连接
1.左外连接
除了返回两张表中所有满足连接条件的行之外,还要返回左表中所有不满足连接条件的行。所谓左表,就是写在LEFT JOIN关键字左边的表
左外连接特点:会将主表的所有要查询的信息显示出来
示例:
select s.sname,x.xuefen ##查询s表的name列和x表的xuefe列
from stu s ##根据join可以得出来自stu表和xuanke表
left join xuanke x ##左外连接选课表,会把没有选课的学生列出来
on s.sid=x.xid; ##条件是s表的sid列等于x表的xid列在这里插入图片描述由表得出:王五没有选课,但是也把他列出来,这就是左外连接的优势

什么情况下会用到左外连接呢??
(1)我们查询时主表有”所有”这个关键词,例如:查询所有学生信息以及他们的选课信息(注:学生表是主表),因为主表有的信息外表不一定有
(2)通俗来说就是主表(左表)的主键列上有的信息,在右表的外键列上找不到时,会使用左外链接

2.右外连接
除了返回两张表中所有满足连接条件的行之外,还要返回右表中所有不满足连接条件的行。所谓右表(外键存在的表),就是写在RIGHT JOIN关键字右边的表
一般没有右外连接,因为右表的外键都来自左表的主键,也就是右表的外键列的信息一般都能在左表的主键列上找到
示例:
select s.sname,x.sid,x.cid,x.xuefen ##查询s表的name列和x表的sid列,cid列和xuefe列
from stu s ##根据join条件可以得出来自stu表和xuanke表
right join xuanke x ##右外连接选课表,会把已经选课的全部学生显示出来
on s.sid=x.xid;

什么情况下会用到右外连接呢??
(1)右表里外键列有的信息在左表的主键列上找不到时,会使用右外链接

注:mysql不支持全连接,也就是不支持左右外连接

给连接查询附加条件
1.在使用左右外连接时,可以在select字句的最后边加上附加条件(and字句或者where字句)
示例:
select s.sname,x.xuefen ##查询s表的name列和x表的xuefe列
from stu s ##根据join可以得出来自stu表和xuanke表
left join xuanke x ##左外连接选课表,会把没有选课的学生列出来
on s.sid=x.xid
where s.name=’张三’; ##只查询s表的sname列为张三的信息 where最后执行
(and) ##and会先执行
2.在经典写法中,也可以在select字句的最后边加上附加条件(使用and,order by , group by 等)
示例:
select s.sname, t.tname, c.cname, x,xuefen ##展示s表的sname列,t表的tname列
c表的cname列,x表的xuefen列
from stu s, tea t, course c, xuanke x ##分别给stu表,tea表等起别名为s,t等

where s.sid=x.sid and t.tid=x.tid and c.cid=x.cid ##s表的sid列等于x表的sid列等
and s.sname=’李三’;

交叉连接
笛卡尔积
如果连接查询没有写任何连接条件,那么一张表中的所有行可以和另一张表中的所有行进行连接,得到的结果集中的总行数就是两张表中总行数的乘积,叫做笛卡尔积
在实际中,应该要避免产生笛卡尔积的连接,特别是对于大表

猜你喜欢

转载自blog.csdn.net/qq_43028054/article/details/93760549