MySQL表与表之间的联系

本文详细介绍了数据库中的多表查询,包括一对一、一对多、多对多关系的建立,以及联合查询、内连接、外连接(左外和右外)的使用方法。此外,还讲解了自连接和子查询的概念及其应用实例,帮助读者深入理解数据库查询的复杂操作。
摘要由CSDN通过智能技术生成

数据准备

CREATE TABLE `stu` (
  `sid` int(11) NOT NULL AUTO_INCREMENT,
  `sname` varchar(25) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` char(6) DEFAULT NULL,
  `score` int(11) DEFAULT NULL,
  `cid` int(11) DEFAULT NULL,
  `groupLeaderId` int(11) DEFAULT NULL,
  PRIMARY KEY (`sid`)
) ENGINE=InnoDB AUTO_INCREMENT=1012 DEFAULT CHARSET=utf8;

CREATE TABLE `class` (
  `cid` int(11) NOT NULL AUTO_INCREMENT,
  `cname` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  `caddress` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

多表查询

表与表之间的关系

一对一

一张表中的一条记录只能与另一张表的一条记录相对应。

比如,一个人只能对应一个身份证号码。

一对一两种建表原则:

  • 外键唯一:主表的主键和从表的外键(唯一),形成主外键关系,外键加上唯一约束unique。
  • 外键是主键:主表的主键和从表的主键形成主外健关系,就是让一张表的主键同时作为另一张表的主键,同时这一张表的主键不能自增。
一对多

一张表中有一条记录可以对应另外一张表中的多条记录:但是反过来,另外—张表的一条记录只能对应第—张表的一条记录,这种关系就是一对多或多对一。如下:

在这里插入图片描述

多对多

一对表中(A)的一条记录能够对应另外一张表(B)中的多条记录;同时B表中的一条记录也能对应A表中的多条记录。要表示多对多的关系,必须创建第三个表,改表通常称为联接表,它将对多对关系划分为两个一对一的关系,并且两个多对多的表的主键都要插入联结表中。如下:

在这里插入图片描述

联合查询

联合查询就是将多个查询结果,纵向拼接在一起。关键字union

语法

-- union 会将完全一致的数据去重
select * from tb_a
union
select * from tb_b

-- union all 会将所有数据保留
select id,name,age from tb_a
union all
select id,name,age from tb_b

注意:

在合并两个表时,两个表的列数、数据类型都要一致!!!!

连接查询

连接查询就是将多个表的查询结果横向拼接后展现。

内连接

语法

select * 
from1 inner join2
on1.字段 =2.字段;

-- 简化写法
select *
from1,2
where.字段 =2.字段;

注意:

内连接只会保留完全符合关联条件的数据。

案例:

-- 查询学生编号为1007的学生名称、学生成绩、班级名称、班级地址
select sid,sname,score,cname,caddress
from stu,class
where stu.cid = class.cid and stu.sid = 1007;
外连接

外连接分为左外连接(left join)和右外连接(right join)。

连接会保留不符合关联条件的数据,左外保留左表中不符合条件的数据,右外表刘右表中不符合条件的数据。

左外连接

语法

-- 左外连接
select *
from1 left outer join2
on1.cid =2.cid;

-- outer 可以省略不写
select *
from1 left join2
on1.cid =2.cid;

案例:

-- 查询学生信息,如果有班级信息就查询班级信息
select *
from stu left outer join class
on stu.cid = class.cid;

在这里插入图片描述

右外连接

语法

-- 右外连接
select *
from1 right outer join2
on1.cid =2.cid;

-- outer 可以省略不写
select *
from1 right join2
on1.cid =2.cid;

案例:

-- 查询学生信息,如果有班级信息就查询班级信息
select *
from stu right outer join class
on stu.cid = class.cid;
自连接

在一张表里引用自己的字段,这个表可以和它自身做连接运算。

语法

对表设置别名

案例:

-- 求1008学生编号、姓名、组长编号和组长姓名
select s.sid,s.sname,z.sid,z.sname
from stu s, stu z
where s.groupLeaderId = z.sid and s.sid = 1008;

子查询(subquery)

子查询就是嵌套查询。嵌套查询的书写顺序,一般是先书写内层查询,再书写外层查询。

嵌套查询,

​ 1、可以嵌套在where后面做为条件

​ 2、可以嵌套在from后面作为一张表

案例:

-- 子查询
-- 查询与张三同一个班级的学生。
select *
from stu
where cid = (
			select cid
			from stu
			where sname = '张三'
);

-- 成绩高于3号班级所有人的学生信息
select *
from stu
where score > (
				select MAX(score)
				from stu
				where cid = 3
);

-- 有2个以上直接组员的学生信息
-- 1)先查询到有两个组员的学生学号
select groupLeaderId
from stu
group by groupLeaderId
having count(groupLeaderId) > 2;
-- 2)再根据学号查询信息
select *
from stu
where sid in (
				select groupLeaderId
				from stu
				group by groupLeaderId
				having count(groupLeaderId) > 2
);

-- 变式2:子查询当做表
select *
from stu s,(select groupLeaderId from stu group by groupLeaderId having count(groupLeaderId) > 2) z
where s.sid = z.groupLeaderId;

stu
group by groupLeaderId
having count(groupLeaderId) > 2
);

– 变式2:子查询当做表
select *
from stu s,(select groupLeaderId from stu group by groupLeaderId having count(groupLeaderId) > 2) z
where s.sid = z.groupLeaderId;


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值