inner join、left join、right join的区别

今天去面试被问到这三个问题,虽然脑子有印象,但还是回答的不太好。

表连接分为:内连接和外连接,其中外连接又分为左连接和右连接。

left join:查询后返回左表中所有记录和右边中联结字段相等的记录。(右边中没有的记录记做null)

right join:查询后返回右表中所有记录和左边中联结字段相等的记录。(左边中没有的记录记做null)

inner join:查询后返回左右两表中联结字段相等的记录。

以下是举例:

mysql> select * from emp;
+-------+------------+---------+--------+
| ename | hiredate   | sal     | deptno |
+-------+------------+---------+--------+
| 123e  | 2018-07-26 | 1000.00 |      1 |
| 123d  | 2018-07-26 | 3000.00 |      2 |
| 123c  | 2018-07-26 | 5000.00 |      1 |
| 123b  | 2018-07-26 | 7000.00 |      3 |
| 123a  | 2018-07-26 | 8000.00 |      4 |
+-------+------------+---------+--------+
5 rows in set (0.00 sec)

mysql> select * from dept;
+--------+-----------+
| deptno | deptname  |
+--------+-----------+
|      1 | ze        |
|      2 | bingze    |
|      3 | zhi       |
|      5 | zhibingze |
+--------+-----------+
4 rows in set (0.00 sec)


1.左连接left join(emp在其左,dept在其右)
mysql> select * from emp left join dept on emp.deptno=dept.deptno;
+-------+------------+---------+--------+--------+----------+
| ename | hiredate   | sal     | deptno | deptno | deptname |
+-------+------------+---------+--------+--------+----------+
| 123e  | 2018-07-26 | 1000.00 |      1 |      1 | ze       |
| 123c  | 2018-07-26 | 5000.00 |      1 |      1 | ze       |
| 123d  | 2018-07-26 | 3000.00 |      2 |      2 | bingze   |
| 123b  | 2018-07-26 | 7000.00 |      3 |      3 | zhi      |
| 123a  | 2018-07-26 | 8000.00 |      4 |   NULL | NULL     |
+-------+------------+---------+--------+--------+----------+
5 rows in set (0.00 sec)

2.右连接right join(dept在其左,dept在其右)
mysql> select * from dept right join emp on emp.deptno=dept.deptno;
+--------+----------+-------+------------+---------+--------+
| deptno | deptname | ename | hiredate   | sal     | deptno |
+--------+----------+-------+------------+---------+--------+
|      1 | ze       | 123e  | 2018-07-26 | 1000.00 |      1 |
|      1 | ze       | 123c  | 2018-07-26 | 5000.00 |      1 |
|      2 | bingze   | 123d  | 2018-07-26 | 3000.00 |      2 |
|      3 | zhi      | 123b  | 2018-07-26 | 7000.00 |      3 |
|   NULL | NULL     | 123a  | 2018-07-26 | 8000.00 |      4 |
+--------+----------+-------+------------+---------+--------+
5 rows in set (0.00 sec)

这里大家会发现左右连接的结果相同,这里我们一定要看好,左右连接两边表名也跟着改变了。

3.右连接right join(emp在其左,dept在其右)
mysql>  select * from emp right join dept on emp.deptno=dept.deptno;
+-------+------------+---------+--------+--------+-----------+
| ename | hiredate   | sal     | deptno | deptno | deptname  |
+-------+------------+---------+--------+--------+-----------+
| 123e  | 2018-07-26 | 1000.00 |      1 |      1 | ze        |
| 123d  | 2018-07-26 | 3000.00 |      2 |      2 | bingze    |
| 123c  | 2018-07-26 | 5000.00 |      1 |      1 | ze        |
| 123b  | 2018-07-26 | 7000.00 |      3 |      3 | zhi       |
| NULL  | NULL       |    NULL |   NULL |      5 | zhibingze |
+-------+------------+---------+--------+--------+-----------+
5 rows in set (0.01 sec)

这时用1和3进行比较,会发现有所不同了。

4内连接inner join

mysql> select * from emp inner join dept on emp.deptno = dept.deptno;
+-------+------------+---------+--------+--------+----------+
| ename | hiredate   | sal     | deptno | deptno | deptname |
+-------+------------+---------+--------+--------+----------+
| 123e  | 2018-07-26 | 1000.00 |      1 |      1 | ze       |
| 123d  | 2018-07-26 | 3000.00 |      2 |      2 | bingze   |
| 123c  | 2018-07-26 | 5000.00 |      1 |      1 | ze       |
| 123b  | 2018-07-26 | 7000.00 |      3 |      3 | zhi      |
+-------+------------+---------+--------+--------+----------+
4 rows in set (0.00 sec)

只显示两边有关联的数据,未关联的数据不显示。

5.该写法等价于内连接(慎用,还是推荐用4)

mysql> select * from emp,dept where emp.deptno=dept.deptno;
+-------+------------+---------+--------+--------+----------+
| ename | hiredate   | sal     | deptno | deptno | deptname |
+-------+------------+---------+--------+--------+----------+
| 123e  | 2018-07-26 | 1000.00 |      1 |      1 | ze       |
| 123d  | 2018-07-26 | 3000.00 |      2 |      2 | bingze   |
| 123c  | 2018-07-26 | 5000.00 |      1 |      1 | ze       |
| 123b  | 2018-07-26 | 7000.00 |      3 |      3 | zhi      |
+-------+------------+---------+--------+--------+----------+
4 rows in set (0.00 sec)

如果不写where条件的话,就是笛卡尔积(emp*dept)。

6.子查询
mysql> select * from emp where deptno in (select deptno from dept );
+-------+------------+---------+--------+
| ename | hiredate   | sal     | deptno |
+-------+------------+---------+--------+
| 123e  | 2018-07-26 | 1000.00 |      1 |
| 123d  | 2018-07-26 | 3000.00 |      2 |
| 123c  | 2018-07-26 | 5000.00 |      1 |
| 123b  | 2018-07-26 | 7000.00 |      3 |
+-------+------------+---------+--------+
4 rows in set (0.00 sec)

总结:是哪一边的连接,就以哪一边为主来做连接。

猜你喜欢

转载自blog.csdn.net/qq_35221138/article/details/79534712