目录
2.4.1 左外连接(包含表1所有数据以及表1表2交集数据)
2.4.2 右外连接 (包含表2所有数据以及表1表2交集数据)
1、多表关系
项目开发中。在进行数据表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个结构之间也存在着各种联系,基本分三种:
- 一对多(多对一)
- 多对多
- 一对一
1.1 一对多(多对一)
案例:部门与员工的关系
关系:一个部门对应多个员工,一个员工对应一个部门
实现:在多的一方建立外键,指向一的一方的主键
1.2 多对多
案例:学生与课程的关系
关系:一个学生可以选择多门课程,一门课程可以供多个学生选择
实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
1.3 一对一
案例:用户与用户详情的关系
关系:一对一关系,多用于单表拆分,将一个表的基础字段放在一张表中,其他详情字段放在另一张表,以提升操作效率
实现:在任意一方加入外键,关联另一方的主键,并且设置外键为唯一的(unique)
2、多表查询概述
员工表:
mysql> select * from emp;
+----+--------+--------------+---------+-----------+------+--------+
| id | name | job | dept_id | managerid | age | salary |
+----+--------+--------------+---------+-----------+------+--------+
| 1 | 张三 | 总裁 | 5 | NULL | 32 | 5000 |
| 2 | 李四 | 项目经理 | 1 | 1 | 42 | 5100 |
| 3 | 王五 | 开发 | 1 | 2 | 52 | 4100 |
| 4 | 老刘 | 开发 | 1 | 3 | 22 | 6100 |
| 5 | 老张 | 开发 | 1 | 4 | 62 | 6100 |
| 6 | 老吕 | NULL | NULL | NULL | 42 | 6100 |
+----+--------+--------------+---------+-----------+------+--------+
部门表:
mysql> select * from dept;
+----+-----------+
| id | name |
+----+-----------+
| 1 | 研发部 |
| 2 | 市场部 |
| 3 | 财务部 |
| 4 | 销售部 |
| 5 | 总经办 |
+----+-----------+
2.1 多表查询(笛卡尔积)
select * from emp,dept;
效果展示:
mysql> select * from emp,dept;
+----+--------+--------------+---------+-----------+------+--------+----+-----------+
| id | name | job | dept_id | managerid | age | salary | id | name |
+----+--------+--------------+---------+-----------+------+--------+----+-----------+
| 1 | 张三 | 总裁 | 5 | NULL | 32 | 5000 | 5 | 总经办 |
| 1 | 张三 | 总裁 | 5 | NULL | 32 | 5000 | 4 | 销售部 |
| 1 | 张三 | 总裁 | 5 | NULL | 32 | 5000 | 3 | 财务部 |
| 1 | 张三 | 总裁 | 5 | NULL | 32 | 5000 | 2 | 市场部 |
| 1 | 张三 | 总裁 | 5 | NULL | 32 | 5000 | 1 | 研发部 |
| 2 | 李四 | 项目经理 | 1 | 1 | 42 | 5100 | 5 | 总经办 |
| 2 | 李四 | 项目经理 | 1 | 1 | 42 | 5100 | 4 | 销售部 |
| 2 | 李四 | 项目经理 | 1 | 1 | 42 | 5100 | 3 | 财务部 |
| 2 | 李四 | 项目经理 | 1 | 1 | 42 | 5100 | 2 | 市场部 |
| 2 | 李四 | 项目经理 | 1 | 1 | 42 | 5100 | 1 | 研发部 |
| 3 | 王五 | 开发 | 1 | 2 | 52 | 4100 | 5 | 总经办 |
| 3 | 王五 | 开发 | 1 | 2 | 52 | 4100 | 4 | 销售部 |
| 3 | 王五 | 开发 | 1 | 2 | 52 | 4100 | 3 | 财务部 |
| 3 | 王五 | 开发 | 1 | 2 | 52 | 4100 | 2 | 市场部 |
| 3 | 王五 | 开发 | 1 | 2 | 52 | 4100 | 1 | 研发部 |
| 4 | 老刘 | 开发 | 1 | 3 | 22 | 6100 | 5 | 总经办 |
| 4 | 老刘 | 开发 | 1 | 3 | 22 | 6100 | 4 | 销售部 |
| 4 | 老刘 | 开发 | 1 | 3 | 22 | 6100 | 3 | 财务部 |
| 4 | 老刘 | 开发 | 1 | 3 | 22 | 6100 | 2 | 市场部 |
| 4 | 老刘 | 开发 | 1 | 3 | 22 | 6100 | 1 | 研发部 |
| 5 | 老张 | 开发 | 1 | 4 | 62 | 6100 | 5 | 总经办 |
| 5 | 老张 | 开发 | 1 | 4 | 62 | 6100 | 4 | 销售部 |
| 5 | 老张 | 开发 | 1 | 4 | 62 | 6100 | 3 | 财务部 |
| 5 | 老张 | 开发 | 1 | 4 | 62 | 6100 | 2 | 市场部 |
| 5 | 老张 | 开发 | 1 | 4 | 62 | 6100 | 1 | 研发部 |
| 6 | 老吕 | NULL | NULL | NULL | 42 | 6100 | 5 | 总经办 |
| 6 | 老吕 | NULL | NULL | NULL | 42 | 6100 | 4 | 销售部 |
| 6 | 老吕 | NULL | NULL | NULL | 42 | 6100 | 3 | 财务部 |
| 6 | 老吕 | NULL | NULL | NULL | 42 | 6100 | 2 | 市场部 |
| 6 | 老吕 | NULL | NULL | NULL | 42 | 6100 | 1 | 研发部 |
+----+--------+--------------+---------+-----------+------+--------+----+-----------+
30 rows in set (0.00 sec)
概述:指从多种表中查询数据
笛卡尔积:笛卡尔乘积是指在数学中,两个集合所有组合情况。
2.2 多表查询的分类
2.2.1 连接查询
内连接:相当于查询A,B交集部分数据
外连接:
左外连接:查询左表所有数据,以及两张表交集部分数据
右外连接:查询右表所有数据,以及两张表交集部分数据
自连接:当前表与自身的连接查询,自连接必须使用表别名
2.3 内连接(表1表2交集数据)
2.3.1 隐式内连接
select * from 表1,表2 where 条件
2.3.2 显示内连接
select * from 表1 join 表2 on 连接条件
2.4 外连接
2.4.1 左外连接(包含表1所有数据以及表1表2交集数据)
select * from 表1 left join 表2 on 条件
2.4.2 右外连接 (包含表2所有数据以及表1表2交集数据)
select * from 表1 right join 表2 on 条件
2.5 自连接(可以是内连接,也可以时外连接)
select * from 表A 别名a join 表A 别名b on 条件
2.6 联合查询(union all)
select * from 表1 union [all] select * from 表2
3、子查询
3.1 基本语法
概念:SQL语句中嵌套select语句,称为嵌套查询,又称子查询。
select * from t1 where column=(select * from t2);
子查询外部的语句可以是insert/update/delete/select的任何一个
3.2 子查询分类
根据子查询结果不同,分为:
- 标量子查询(子查询结果为单个值)
- 列子查询(子查询结果为一列)
- 行子查询(子查询结果为一行)
- 表子查询(子查询结果为多行多列)
根据子查询位置,分为:where之后、from之后、select之后。
3.2.1 变量子查询
子查询返回的结果是单个值,最简单形式,这种子查询为标量子查询。
3.2.2 列子查询
子查询返回值是一列(可以是多行),这种子查询为列子查询。
常用的操作符:in、not in、any、some、all
操作符 | 描述 |
in | 在指定的集合范围之内,多选一 |
not in | 不在指定的集合范围之内 |
any | 子查询返回列表中,有一个满足即可 |
some | 与any相同 |
all | 子查询返回列表的所有值都必须满足 |
例子:查询销售部和市场部的所有员工信息。
select * from emp where dept_id in (select id from dept where name = '销售部' or name = '市场部');
效果展示:
mysql> select * from emp where dept_id in (select id from dept where name = '销售部' or name = '市场部');
+----+--------+--------+---------+-----------+------+--------+
| id | name | job | dept_id | managerid | age | salary |
+----+--------+--------+---------+-----------+------+--------+
| 3 | 王五 | 开发 | 4 | 2 | 52 | 4100 |
+----+--------+--------+---------+-----------+------+--------+
1 row in set (0.00 sec)
3.2.3 行子查询
子查询返回值是一行(可以是多列),这种子查询为行子查询。
常用操作符:=、<>、in、not in
3.2.4 表子查询
子查询结果为多行多列,这种子查询为表子查询。
常用操作符:in