题目
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: ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/20211224105840.png) ## 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 相同的行记录,并组合起来 ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/20211226110731.png) 来看实际的执行结果: ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/20211224111647.png) 需要注意的是,如果不指定 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; ``` ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/20211224112015.png) 光看这个例子大伙儿可能觉得笛卡尔积没啥用,其实还是很常见的,举个例子:如果 A 表示某学校学生的集合,B 表示该学校所有课程的集合,则 A 与 B 的笛卡尔积就表示这个学校所有可能的选课情况。 另外,多提一嘴,可能有小伙伴还见过 cross join,在 MySQL 中 cross join 与 inner join 的作用是一样的。并且,可以直接省略掉 cross 或者 inner 关键字: ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/20211224112614.png) ## 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 代替。 ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/20211226110742.png) 来看实际的执行结果: ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/20211224111502.png) ## 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 代替。 ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/20211226110754.png) 来看实际的执行结果: ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/20211224111624.png) ## full join 回顾下上面三张图,小伙伴们不知道有没有感觉缺了点什么,为啥没有把两个圆都填满的? ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/20211226110711.png) 把两个圆都填满的学名叫作 **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; ``` ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/20211224112841.png)