版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ycd500756/article/details/84178542
定义:
连接查询又称为多表查询,当查询的字段来源于多个表时,那么就会用到多表查询。
分类
按照年代分类
- sql92标准:在Mysql中只是支持内连接;
- sql99标准:在Mysql中支持了内连接、外连接(左外连接、右外连接)和交叉连接;也是推荐的一种写法。
按照功能分类
- 内连接:等值连接、非等值连接、自连接;
- 外连接: 左外连接、右外连接、全外连接(mysql中不支持)
- 交叉连接。
数据准备
以下的sql语句均在MySQL数据库中运行
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.22 |
+-----------+
1 row in set
1.部门表(tb_dept)
mysql> select * from tb_dept;
+----+-----------+
| id | dept_name |
+----+-----------+
| 1 | 开发部 |
| 2 | 测试部 |
| 3 | 销售部 |
| 4 | HR部 |
| 5 | 服务部 |
+----+-----------+
5 rows in set
2.员工信息表
mysql> select * from tb_emp;
+----+--------+---------+
| id | name | dept_id |
+----+--------+---------+
| 1 | Mark | 1 |
| 2 | Sammi | 2 |
| 3 | Abel | 2 |
| 4 | Dannel | 4 |
| 7 | Eason | 3 |
| 8 | Sa | 1 |
| 10 | other | 0 |
+----+--------+---------+
7 rows in set
inner join
语法结构
select 查询列表
from 表1 表1别名
inner join 表2 表2别名
on 连接条件
where
group by
order by
limit
inner join(内连接)特点:
1.基于连接条件将两张表的目标列组合取交集在一起,组成新的一张结果表;
2.inner
可以省略;
3.筛选条件放在where
后面,连接条件方法放在on
后面;
4.在表设计时连接条件的字段的类型和长度最好保持一致。
demo:员工表和部门表进行内连接,连接条件为:员工表中的部门id等于部门表的id。
mysql> select * from tb_emp A inner join tb_dept B on A.dept_id=B.id;
+----+--------+---------+----+-----------+
| id | name | dept_id | id | dept_name |
+----+--------+---------+----+-----------+
| 1 | Mark | 1 | 1 | 开发部 |
| 2 | Sammi | 2 | 2 | 测试部 |
| 3 | Abel | 2 | 2 | 测试部 |
| 4 | Dannel | 4 | 4 | HR部 |
| 7 | Eason | 3 | 3 | 销售部 |
| 8 | Sa | 1 | 1 | 开发部 |
+----+--------+---------+----+-----------+
6 rows in set
sql92写法:
select * from tb_emp A, tb_dept B where A.dept_id=B.id;
left join
left join(左连接):显示左表的全部记录以及右表符合条件的记录;如果右表中没有匹配数据则显示为null
1.员工表 左连接 部门表
mysql> select * from tb_emp A left join tb_dept B on A.dept_id=B.id;
+----+--------+---------+------+-----------+
| id | name | dept_id | id | dept_name |
+----+--------+---------+------+-----------+
| 1 | Mark | 1 | 1 | 开发部 |
| 8 | Sa | 1 | 1 | 开发部 |
| 2 | Sammi | 2 | 2 | 测试部 |
| 3 | Abel | 2 | 2 | 测试部 |
| 7 | Eason | 3 | 3 | 销售部 |
| 4 | Dannel | 4 | 4 | HR部 |
| 10 | other | 0 | NULL | NULL |
+----+--------+---------+------+-----------+
7 rows in set
2.部门表 左连接 员工表
mysql> select * from tb_dept A left join tb_emp B on A.id=B.dept_id;
+----+-----------+------+--------+---------+
| id | dept_name | id | name | dept_id |
+----+-----------+------+--------+---------+
| 1 | 开发部 | 1 | Mark | 1 |
| 2 | 测试部 | 2 | Sammi | 2 |
| 2 | 测试部 | 3 | Abel | 2 |
| 4 | HR部 | 4 | Dannel | 4 |
| 3 | 销售部 | 7 | Eason | 3 |
| 1 | 开发部 | 8 | Sa | 1 |
| 5 | 服务部 | NULL | NULL | NULL |
+----+-----------+------+--------+---------+
7 rows in set
right join
right join(右连接):显示右表的全部记录以及左表符合条件的记录;如果左表中没有匹配数据则显示为null
1.部门表 右连接 员工表 (查询的结果和 员工表 左连接 部门表 是一样的)
mysql> select * from tb_dept A right join tb_emp B on A.id=B.dept_id;
+------+-----------+----+--------+---------+
| id | dept_name | id | name | dept_id |
+------+-----------+----+--------+---------+
| 1 | 开发部 | 1 | Mark | 1 |
| 1 | 开发部 | 8 | Sa | 1 |
| 2 | 测试部 | 2 | Sammi | 2 |
| 2 | 测试部 | 3 | Abel | 2 |
| 3 | 销售部 | 7 | Eason | 3 |
| 4 | HR部 | 4 | Dannel | 4 |
| NULL | NULL | 10 | other | 0 |
+------+-----------+----+--------+---------+
7 rows in set
2.员工表 右连接 部门表 (查询的结果和 部门表 左连接 员工表 是等介的)
mysql> select * from tb_emp A right join tb_dept B on A.dept_Id=B.id;
+------+--------+---------+----+-----------+
| id | name | dept_id | id | dept_name |
+------+--------+---------+----+-----------+
| 1 | Mark | 1 | 1 | 开发部 |
| 2 | Sammi | 2 | 2 | 测试部 |
| 3 | Abel | 2 | 2 | 测试部 |
| 4 | Dannel | 4 | 4 | HR部 |
| 7 | Eason | 3 | 3 | 销售部 |
| 8 | Sa | 1 | 1 | 开发部 |
| NULL | NULL | NULL | 5 | 服务部 |
+------+--------+---------+----+-----------+
7 rows in set
cross join
cross join:交叉连接或者又称为 笛卡尔连接或者叉乘连接。在cross join 中可以不使用on。如果进行连接操作的表记录过多的话,那么尽可能避免使用cross join。
1.部门表和与员工表进行交叉连接
mysql> select * from tb_emp A cross join tb_dept B ;
+----+--------+---------+----+-----------+
| id | name | dept_id | id | dept_name |
+----+--------+---------+----+-----------+
| 1 | Mark | 1 | 1 | 开发部 |
| 1 | Mark | 1 | 2 | 测试部 |
| 1 | Mark | 1 | 3 | 销售部 |
| 1 | Mark | 1 | 4 | HR部 |
| 1 | Mark | 1 | 5 | 服务部 |
| 2 | Sammi | 2 | 1 | 开发部 |
| 2 | Sammi | 2 | 2 | 测试部 |
| 2 | Sammi | 2 | 3 | 销售部 |
| 2 | Sammi | 2 | 4 | HR部 |
| 2 | Sammi | 2 | 5 | 服务部 |
| 3 | Abel | 2 | 1 | 开发部 |
| 3 | Abel | 2 | 2 | 测试部 |
| 3 | Abel | 2 | 3 | 销售部 |
| 3 | Abel | 2 | 4 | HR部 |
| 3 | Abel | 2 | 5 | 服务部 |
| 4 | Dannel | 4 | 1 | 开发部 |
| 4 | Dannel | 4 | 2 | 测试部 |
| 4 | Dannel | 4 | 3 | 销售部 |
| 4 | Dannel | 4 | 4 | HR部 |
| 4 | Dannel | 4 | 5 | 服务部 |
| 7 | Eason | 3 | 1 | 开发部 |
| 7 | Eason | 3 | 2 | 测试部 |
| 7 | Eason | 3 | 3 | 销售部 |
| 7 | Eason | 3 | 4 | HR部 |
| 7 | Eason | 3 | 5 | 服务部 |
| 8 | Sa | 1 | 1 | 开发部 |
| 8 | Sa | 1 | 2 | 测试部 |
| 8 | Sa | 1 | 3 | 销售部 |
| 8 | Sa | 1 | 4 | HR部 |
| 8 | Sa | 1 | 5 | 服务部 |
| 10 | other | 0 | 1 | 开发部 |
| 10 | other | 0 | 2 | 测试部 |
| 10 | other | 0 | 3 | 销售部 |
| 10 | other | 0 | 4 | HR部 |
| 10 | other | 0 | 5 | 服务部 |
+----+--------+---------+----+-----------+
35 rows in set
结果集的记录数=员工表(7条记录)*部门表(5表记录)=35条记录;该现象称为笛卡尔积现象。
该查询结果和下面的sql结果是相等的。都为逐步取出员工表的每一行记录去和部门表的每一条记录进行组合。
select * from tb_emp , tb_dept ;