题目
innerjoin、leftjoin、rightjoin、union 的区别
答案
@[toc]
---
MySQL 中常见的有三种用法:
```sql
select * from table1 inner join table2 on condition
select * from table1 left join table2 on condition
select * from table1 right join table2 on condition
```
- inner join:内连接(等值连接)
- left join:左连接
- right join:右连接
下面用例子来解释这三种用法,假设有两张表,用户表 user 和部门表 depart:

## inner join
```sql
select user.name, user.age, depart.department
from user inner join depart
on user.name = depart.name;
```
inner join 获取同时符合两张表的数据并组合起来。
在这个例子中,就是在 user 表和 depart 表中找到 name 相同的行记录,并组合起来

来看实际的执行结果:

需要注意的是,如果不指定 on 条件进行过滤的话,取得的结果就是两张表的笛卡尔积
> 什么是笛卡尔积 ?
>
> 举个例子,两个集合 A{1, 2, 3} 和 B{a, b, c},则两个集合的笛卡尔积为 {1a, 1b, 1c, 2a, 2b, 2c, 3a, 3b, 3c}
```sql
select user.name, user.age, depart.department
from user inner join depart;
```

光看这个例子大伙儿可能觉得笛卡尔积没啥用,其实还是很常见的,举个例子:如果 A 表示某学校学生的集合,B 表示该学校所有课程的集合,则 A 与 B 的笛卡尔积就表示这个学校所有可能的选课情况。
另外,多提一嘴,可能有小伙伴还见过 cross join,在 MySQL 中 cross join 与 inner join 的作用是一样的。并且,可以直接省略掉 cross 或者 inner 关键字:

## left join
```sql
select user.name, user.age, depart.department
from user left join depart
on user.name = depart.name;
```
left join 取得左表的所有记录,即使右边这个表没有对应的匹配记录(如果没有相匹配的话,用 null 代替)。
在这个例子中,就是获取 user 表的所有记录,然后根据 on 条件去 depart 表中查询,如果有相同的 name,就组合起来,如果 depart 表中找不到和 user 表具有相同 name 的记录,就用 NULL 代替。

来看实际的执行结果:

## right join
```sql
select user.name, user.age, depart.department
from user right join depart
on user.name = depart.name;
```
和 left join 相反,right join 取得右表的所有记录,即使左边这个表没有对应的匹配记录(如果没有相匹配的话,用 null 代替)。
在这个例子中,就是获取 depart 表的所有记录,然后根据 on 条件去 user 表中查询,如果有相同的 name,就组合起来,如果 user 表中找不到和 depart 表具有相同 name 的记录,就用 NULL 代替。

来看实际的执行结果:

## full join
回顾下上面三张图,小伙伴们不知道有没有感觉缺了点什么,为啥没有把两个圆都填满的?

把两个圆都填满的学名叫作 **full join**,But,MySQL 中并没有 full join 的语法,需要借助 `union` 关键字来实现:
```sql
select user.name, user.age, depart.department
from user left join depart
on user.name = depart.name
union
select user.name, user.age, depart.department
from user right join depart
on user.name = depart.name;
```

