今天去面试被问到这三个问题,虽然脑子有印象,但还是回答的不太好。
表连接分为:内连接和外连接,其中外连接又分为左连接和右连接。
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)
总结:是哪一边的连接,就以哪一边为主来做连接。