目录

一 多表关系

1 一对一关系

2 一对多/多对一关系

3 多对多关系

4 外键约束

在创建表时设置外键约束

在创建表后设置外键约束

多对多关系的外键约束

二 多表联查

1 交叉连接查询

2 内连接查询

3 外连接查询

4 子查询

5 子查询关键字

子查询关键字 all

子查询关键字 any和some

子查询关键字 in

子查询关键字 exists

6 自关联查询


一 多表关系

实际开发中,一个项目表通常需要多张表才能完成。例如一个商城项目就需要分类表,商品表,订单表等多张表,且这些表的数据之间存在一定关系。MySQL多表之间的关系可以概括为:一对一,一对多,多对多。

1 一对一关系

例如,一个学生只有一张身份证,一张身份证只能对应一个学生。可在任一表中添加唯一外键,指向另一方主键,确保一对一关系。一般一对一关系很少见,遇到一对一关系的表最好是合并表。

2 一对多/多对一关系

例如,一个部门有多个员工,一个员工只能对应一个部门。在多的一方建立外键,指向一的一方的主键

3 多对多关系

例如,一个学生可以选择很多门课程,一个课程可以被多个学生选择。多对多关系实现需要借助第三张中间表。中间表至少包含两个字段,将多对多的关系拆成一对多的关系,中间表至少要有两个外键,这两个外键分别指向原来的两张表的主键

4 外键约束

MySQL外键约束(foreign key)是表的一个特殊字段,经常与主键约束一起使用。对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表,外键所在的表就是从表。外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。

定义一个外键时要遵守以下规则

  • 主表必须已经存在于数据库中,或者是当前正在创建的表
  • 必须为主表定义主键
  • 主键不能包含空值,但允许外键中包含空值。也就是说,只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。
  • 在主表的表名后面指定列名或者列名的组合,这个列或列的组合必须是主表的主键或候选键。
  • 外键中列的数目必须和主表中主键列的数目相同。
  • 外键中列的数据类型必须和主表主键中的对应列的数据类型相同。

操作-创建外键约束:在create table 语句中,通过foreign key关键字来指定外键

语法格式:[constraint <外键名>] foreign key 字段名 [, 字段名2, .....] references <主表名> 主键列 [, 主键列2, ......]

在创建表时设置外键约束

create database mydb3;
use mydb3;
-- 创建外键约束
-- 创建部门表 主表
create table if not exists dept(
deptno varchar(20) primary key,# 部门号
name varchar (20) # 部门名
);
-- 创建员工表 从表,并创建外键约束
-- [constraint <外键名>] foreign key 字段名 [,字段名2...] references <主表名> 主键列1 [,主键列2...]
create table if not exists emp(
eid varchar(20) primary key,
ename varchar(20),
age int,
deptid varchar(20),#所属部门
constraint empfk foreign key(deptid) references dept(deptno)
);

在创建表后设置外键约束

外键约束可以在修改表时添加,添加外键约束的前提是:从表中的外键列数据必须与主表中主键列数据一致或者没有数据。

语法格式:alter table <数据表名> add constraint <外键名> foreign key (列名) references <主表名> (列名)

-- 创建部门表2  主表
create table if not exists dept2(
deptno varchar(20) primary key,# 部门号
name varchar (20) # 部门名
);
-- 创建员工表2 从表
create table if not exists emp2(
eid varchar(20) primary key,
ename varchar(20),
age int,
deptid varchar(20)#所属部门
);
alter table emp2 add constraint emp2fk foreign key(deptid) references dept2(deptno);

删除数据:主表的数据被从表依赖时不能删除,否则可以删除。从表的数据可以随便删除

删除外键约束

alter table emp2 drop foreign key    emp2fk;

多对多关系的外键约束

-- 学生表和课程表(多对多)-- 1 创建学生表student(左侧主表)create table if not exists student(sid int primary key auto_increment,name varchar(20),age int,gender varchar(20));-- 2 创建课程表course(右侧主表)create table course(cid  int primary key auto_increment,cidname varchar(20));
-- 3创建中间表student_course/score(从表)create table score(sid int,cid int,score double);-- 4建立外键约束(2次)alter table score add foreign key(sid) references student(sid);
alter table score add foreign key(cid) references course(cid);

二 多表联查

多表查询就是同时查询两个或者两个以上的表,因为有时候用户在查看数据时需要显示的数据来自多张表

数据准备

use mydb3;-- 创建部门表
create table if not exists dept3(deptno varchar(20) primary key ,  -- 部门号name varchar(20) -- 部门名字
);-- 创建员工表
create table if not exists emp3(eid varchar(20) primary key , -- 员工编号ename varchar(20), -- 员工名字age int,  -- 员工年龄dept_id varchar(20)  -- 员工所属部门
);
-- 给dept3表添加数据
insert into dept3 values('1001','研发部');
insert into dept3 values('1002','销售部');
insert into dept3 values('1003','财务部');
insert into dept3 values('1004','人事部');
-- 给emp3表添加数据
insert into emp3 values('1','乔峰',20, '1001');
insert into emp3 values('2','段誉',21, '1001');
insert into emp3 values('3','虚竹',23, '1001');
insert into emp3 values('4','阿紫',18, '1001');
insert into emp3 values('5','扫地僧',85, '1002');
insert into emp3 values('6','李秋水',33, '1002');
insert into emp3 values('7','鸠摩智',50, '1002');
insert into emp3 values('8','天山童姥',60, '1003');
insert into emp3 values('9','慕容博',58, '1003');
insert into emp3 values('10','丁春秋',71, '1005');

1 交叉连接查询

交叉连接查询返回被链接的两个表所有数据行的笛卡尔积,笛卡尔积可以理解为一张表的每一行去和另一张表的任意一行进行匹配。假如a表有m行数据,b表有n行数据,则返回m*n行数据,所以笛卡尔积会产生很多冗余数据,后期的其他查询可以在该集合的基础上进行条件筛选

格式:select * from 表1,表2,表3....;

select * from dept3,emp3;

2 内连接查询

内连接查询求多张表的交集

格式:

隐式内连接:select * from A,B where 条件;

显式内连接:select * from A inner join B on 条件;

查询每个部门所属员工

select * from dept3,emp3 where dept3.deptno = emp3.deptid;
select * from dept3 inner join emp3 on dept3.deptno = emp3.deptid;

查询研发部和销售部的所属员工

select * from dept3 a,emp3 b where a.deptno=b.deptid and (name = '研发部' or name ='销售部');
select * from dept3 a join emp3 b on a.deptno=b.deptid and name in ('研发部','销售部');

查询每个部门的员工数,并升序排列

select a.name,a.deptno,count(*) as totalcnt from dept3 a,emp3 b where a.deptno=b.deptid group by a.deptno,a.name order by totalcnt;
select a.name,a.deptno,count(*) as totalcnt from dept3 a join emp3 b on a.deptno=b.deptid group by a.deptno,a.name order by totalcnt;

查询人数大于等于3的部门并按人数降序

select a.name,a.deptno,count(*) as tocnt from dept3 a,emp3 b where a.deptno=b.deptid group by a.deptno,a.name having tocnt >=3 order by tocnt desc;
select a.name,a.deptno,count(*) as tocnt from dept3 a join emp3 b on a.deptno=b.deptid group by a.deptno,a.name having tocnt >=3 order by tocnt desc;

3 外连接查询

左外连接查询:select * from A left outer join B on 条件;

右外连接查询:select * from A right outer join B on 条件;

满外连接查询:select * from A full outer join B on 条件;

注意:Oracle里面有full join,但是在MySQL对full join的支持不好,我们可以用union

查询哪些部门有员工,哪些部门没有员工

use mydb3;
select * from dept3 left outer join emp3 on dept3.deptno = emp3.dept_id;

查询哪些员工有对应的部门,哪些没有

select * from dept3 a right join emp3 b on a.deptno=b.deptid;

使用union关键字实现左外连接和右外连接的并集

select * from dept3 a left join emp3 b on a.deptno = b.deptid
union
select * from dept3 a right join emp3 b on a.deptno=b.deptid;

4 子查询

子查询就是指在一个完整的查询语句中,嵌套若干个不同功能的小查询,从而一起完成复杂查询的一种编写模式,通俗讲就是包含select嵌套的查询

子查询可以返回的数据类型一共分四种

  • 单行单列:返回的是一个具体列的内容,可以理解为一个单值数据
  • 单行多列:返回一行数据中多个列的内容
  • 多行单列:返回多行记录中同一列的内容,相当于给出了一个操作范围
  • 多行多列:查询返回结果是一张临时表

查询年龄最大的员工信息,显示信息包含员工号、员工名字,员工年龄

select * from emp3 where age = (select max(age) from emp3);# 单行单列,可以作为一个值来用

查询年研发部和销售部的员工信息,包含员工号、员工名字

-- 方式一关联查询
select * from dept3 a join emp3 b on a.deptno=b.deptid and (name='研发部' or name = '销售部')
-- 方式二子查询
select deptno from dept3 where name = '研发部' or name = '销售部';
select * from emp3 where deptid in (select deptno from dept3 where name = '研发部' or name = '销售部');# 多行单列 多个值

查询研发部20岁以下的员工信息,包括员工号、员工名字,部门名字

-- 关联查询
select * from dept3 a join emp3 b on a.deptno=b.deptid and (name='研发部' and age < 30);
-- 子查询
select * from dept3 where name = '研发部'; #一行多列,在部门表中查询研发信息
select * from emp3 where age <30; # 查询员工表中年龄小于30的
select * from (select * from dept3 where name = '研发部') t1 join (select * from emp3 where age <30) t2 on t1.deptno = t2.deptid; #将以上两个查询结果关联查询 多行多列

5 子查询关键字

子查询关键字 all

格式:select …from …where c > all(查询语句)  ,

等价于 select ...from ... where c > result1 and c > result2 and c > result3。ALL可以与=、>、>=、<、<=、<>结合是来使用,分别表示等于、大于、大于等于、小于、小于等于、不等于其中的其中的所有数据。ALL表示指定列中的值必须要大于子查询集的每一个值,即必须要大于子查询集的最大值;如果是小于号即小于子查询集的最小值。同理可以推出其它的比较运算符的情况。

查询年龄大于‘1003’部门所有年龄的员工信息

select * from emp3 where age >all(select age from emp3 where deptid ='1003');

查询不属于任何一个部门的员工信息

select * from emp3 where deptid !=all(select deptno from dept3);

子查询关键字 any和some

格式:select …from …where c > any(查询语句)

等价于:select ...from ... where c > result1 or c > result2 or c > result3。ANY可以与=、>、>=、<、<=、<>结合是来使用,分别表示等于、大于、大于等于、小于、小于等于、不等于其中的其中的任何一个数据。表示制定列中的值要大于子查询中的任意一个值,即必须要大于子查询集中的最小值。同理可以推出其它的比较运算符的情况。some 和any的作用一样,some可以理解为any的别名

查询年龄大于‘1003’部门任意一个员工年龄的员工信息

select * from emp3 where age >any(select age from emp3 where deptid ='1003') and deptid != '1003';

子查询关键字 in

格式:select …from …where c in(查询语句)

等价于:select ...from ... where c = result1 or c = result2 or c = result3。in关键字用于判断某个记录的值,是否在指定的集合中,在in关键字前加上not可与将条件反过来

查询研发部和销售部的员工信息,包含员工号、员工名字

select * from emp3 where deptid in (select deptno from dept3 where name = '研发部' or name = '销售部');

子查询关键字 exists

格式:select …from …where exists(查询语句)

该子查询如果“有数据结果”(至少返回一行数据), 则该EXISTS() 的结果为“true”,外层查询执行,该子查询如果“没有数据结果”(没有任何数据返回),则该EXISTS()的结果为“false”,外层查询不执行。EXISTS后面的子查询不返回任何实际数据,只返回真或假,当返回真时 where条件成立。注意,EXISTS关键字,比IN关键字的运算效率高,因此,在实际开发中,特别是大数据量时,推荐使用EXISTS关键字。

查询公司是否有大于60岁的员工,有则输出

select * from emp3 a where exists(select * from emp3 where a.age>60);
select * from emp3 where eid in(select eid from emp3 where age>60);

查询有所属部门的员工信息

select * from emp3 a where exists (select * from dept3 b where a.deptid = b.deptno);
select * from emp3 a where deptid in (select deptno from dept3 b where a.deptid = b.deptno);

6 自关联查询

MySQL有时在信息查询时需要进行对表自身进行关联查询,即一张表自己和自己关联,一张表当成多张表来用。注意自关联时表必须给表起别名。

格式:select 字段列表 from 表1 a , 表1 b where 条件; 或者 select 字段列表 from 表1 a [left] join 表1 b on 条件;

-- 创建表,并建立自关联约束
create table t_sanguo(eid int primary key ,ename varchar(20),manager_id int,foreign key (manager_id) references t_sanguo (eid)  -- 添加自关联约束
);
-- 添加数据
insert into t_sanguo values(1,'刘协',NULL);
insert into t_sanguo values(2,'刘备',1);
insert into t_sanguo values(3,'关羽',2);
insert into t_sanguo values(4,'张飞',2);
insert into t_sanguo values(5,'曹操',1);
insert into t_sanguo values(6,'许褚',5);
insert into t_sanguo values(7,'典韦',5);
insert into t_sanguo values(8,'孙权',1);
insert into t_sanguo values(9,'周瑜',8);
insert into t_sanguo values(10,'鲁肃',8);

查询每个三国人物和他的上级信息

select * from sanguo a, sanguo b where a.managerid = b.eid;
select a.ename,b.ename from sanguo a ,sanguo b where a.managerid = b.eid;

查询所有员工和上级

select a.ename,b.ename from sanguo a left join sanguo b where a.managerid = b.eid;

查询所有人物,上级,上上级

select a.ename,b.ename,c.ename from sanguo a left join sanguo b on a.managerid=b.eid left join sanguo c on b.managerid = c.eid;

SQL自学总结四 MySQL多表操作相关推荐

  1. 数据库 MySQL 之 表操作、存储引擎

    数据库 MySQL 之 表操作.存储引擎 浏览目录 创建(复制) 删除 修改 查询 存储引擎介绍 一.创建(复制) 1.语法: 1 2 3 4 5 CREATE TABLE 表名(     字段名1 ...

  2. 关于MySQL分表操作的研究

    关于MySQL分表操作的研究 一般来说,当我们的数据库的数据超过了100w记录的时候就应该考虑分表或者分区了,这次我来详细说说分表的一些方法.首先,我们需要想好到底分多少个表,前提当然是满足应用.这里 ...

  3. MYSQL数据库表操作pdf

    <MYSQL数据库表操作pdf> 下载地址: 网盘下载 转载于:https://www.cnblogs.com/long12365/p/9731023.html

  4. 【MySQL多表操作练习】

    多表操作练习 > > > MySQL基础 > > > MySQL的多表操作查询 > > > MySQL多表操作练习 > > > ...

  5. 【MySQL】表操作和库操作

    文章目录 概念 库操作 1.创建数据库 2.删除数据库 3.选择数据库 4.显示数据库列表 表操作 1.创建数据表CREATE 2.删除数据表DROP 3.插入数据INSERT 4.更新数据UPDAT ...

  6. Mysql基础——表操作

    ** 一.Mysql的表数据类型 1. 整型--INT(显示宽度) 其实是显示宽度,因为整型的显示宽度,对数值大小无影响,只是当设置了zerofill的时候,在显示的时候补0而已. 2. 浮点型与定点 ...

  7. qt mysql怎么选表_Qt的Mysql数据库表操作(1)

    Qt中的QSqlDatabase.QSqlQueryModel.QSqlRecord.QSqlTableModel等类为我们提供了快速开发数据库的方式,支持多种数据库连接,例如oracle,db2,M ...

  8. mysql 数据表操作 存储引擎介绍

    一 什么是存储引擎? 存储引擎就是表的类型. mysql中建立的库===>文件夹 库中建立的表===>文件 现实生活中我们用来存储数据的文件有不同的类型,每种文件类型对应各自不同的处理机制 ...

  9. mysql怎么多表备份_学习MySQL多表操作和备份处理

    [IT168 服务器学院]前面我们熟悉了数据库和数据库表的基本操作,现在我们再来看看如何操作多个表. 多表操作 在一个数据库中,可能存在多个表,这些表都是相互关联的.我们继续使用前面的例子.前面建立的 ...

最新文章

  1. 在Angular4中使用ng2-baidu-map详解
  2. OpenYurt — Overview
  3. rocketmq中的broker设计与实现
  4. hadoop实战--搭建开发环境及编写Hello World
  5. 深入制造 云计算大数据与智能制造论坛将于6月16日召开
  6. 数据库(Mysql)背后的数据结构-学习
  7. 1109: 胥哥的DOTA-水题(直接做,时间也不超限)
  8. Docker入门系列之三:如何将dockerfile制作好的镜像发布到Docker hub上
  9. 如何清理Virtualbox虚拟机VDI镜像文件的空间大小
  10. 01.MVC5安装Ext.Net
  11. JavaScript unshift()函数移入数据到数组第一位
  12. ssh等价性的一些疑惑
  13. JVM内存模型及分区
  14. Axure下载安装-汉化-注册码
  15. 如何从CPU顶盖获取有用信息
  16. STAMP:Short-TermAttention/MemoryPriorityModelfor Session-basedRecommendation
  17. 保研面试复习之计算机网络篇
  18. 从零开始Tableau | 10.表计算-基础
  19. C++中常见的两种二义性问题及其解决方式
  20. linux ln -sv命令,linux ln 命令详解

热门文章

  1. 【路径规划】基于DWA实现机器人动态避障附matlab代码
  2. TSINGSEE青犀视频云边端架构RTSP/RTMP/GB28181智能分析平磁盘录像云端存储出现问题怎么办?
  3. 2022年全球最具技术实力的的智能合约安全审计公司推荐
  4. CentOS7系统管理与运维实战 (王亚飞著) 完整pdf扫描版
  5. DB2的substr错误问题
  6. Week9作业ABC
  7. 谈谈如何更有效率的交换友情链接
  8. 网络布线与综合布线系统学习
  9. 为什么protobuf这么快
  10. RPKM、FPKM和TPM的区别