SQL之各个join的区别

1.inner join(join)

语法:

SELECT column_name(s)
FROM table1
INNER JOIN table2
ON table1.column_name=table2.column_name;

或者

SELECT column_name(s)
FROM table1
JOIN table2
ON table1.column_name=table2.column_name;

说明:
会对比table1和table2的行,如果table1中的行在table2中也有,即返回,如果没有则不处理
在这里插入图片描述

示例:

stu表存放学生信息,grade表存放学生的成绩信息,
注意!并不是每一个学生都有成绩

mysql> select * from stu;
+----+------+-----+-----+
| id | name | sex | age |
+----+------+-----+-----+
|  1 | hml  | b   |   1 |
|  2 | aaa  | g   |   2 |
|  3 | sss  | b   |   3 |
|  4 | bbb  | g   |   2 |
|  5 | rrr  | b   |   3 |
|  6 | fff  | b   |   2 |
+----+------+-----+-----+
6 rows in set (0.01 sec)

mysql> select * from grade;
+----+------+-------+
| id | name | score |
+----+------+-------+
|  1 | aaa  |    80 |
|  2 | bbb  |    90 |
|  3 | sss  |    85 |
|  4 | rrr  |    90 |
|  5 | yyy  |    90 |
|  6 | xxx  |    80 |
+----+------+-------+
6 rows in set (0.00 sec)

查询stu表中在grade表中有成绩的name和age:(两种方式)

mysql> select a.name,a.age,b.score
	   from stu a join grade b 
	   on a.name = b.name;
+------+-----+-------+
| name | age | score |
+------+-----+-------+
| aaa  |   2 |    80 |
| bbb  |   2 |    90 |
| sss  |   3 |    85 |
| rrr  |   3 |    90 |
+------+-----+-------+
mysql> select a.name,a.age,b.score 
	   from stu a,grade b
	   where a.name = b.name;
+------+-----+-------+
| name | age | score |
+------+-----+-------+
| aaa  |   2 |    80 |
| bbb  |   2 |    90 |
| sss  |   3 |    85 |
| rrr  |   3 |    90 |
+------+-----+-------+

2.left join

语法:

SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name=table2.column_name;

或者

SELECT column_name(s)
FROM table1
LEFT OUTER JOIN table2
ON table1.column_name=table2.column_name;

说明:
会返回table1全部行,在table2中没有的展示为null
在这里插入图片描述
示例:
同上例中的数据,仅仅该变join类型,我们看结果:

mysql> select a.name,a.age,b.score 
	   from stu a  left join grade b
	   on a.name = b.name;
+------+-----+-------+
| name | age | score |
+------+-----+-------+
| aaa  |   2 |    80 |
| bbb  |   2 |    90 |
| sss  |   3 |    85 |
| rrr  |   3 |    90 |
| hml  |   1 |  NULL |
| fff  |   2 |  NULL |
+------+-----+-------+

3.right join

语法:

SELECT column_name(s)
FROM table1
RIGHT JOIN table2
ON table1.column_name=table2.column_name;

或:

SELECT column_name(s)
FROM table1
RIGHT OUTER JOIN table2
ON table1.column_name=table2.column_name;

说明:
会将左表没有的行展示为null
在这里插入图片描述
示例:
同上例数据,换成right join的结果:

mysql> select a.name,a.age,b.score 
	   from stu a right join grade b 
	   on a.name = b.name;
+------+------+-------+
| name | age  | score |
+------+------+-------+
| aaa  |    2 |    80 |
| sss  |    3 |    85 |
| bbb  |    2 |    90 |
| rrr  |    3 |    90 |
| NULL | NULL |    90 |
| NULL | NULL |    80 |
+------+------+-------+

4.full join

语法:

SELECT column_name(s)
FROM table1
FULL OUTER JOIN table2
ON table1.column_name=table2.column_name;

说明:
FULL OUTER JOIN 关键字只要左表(table1)和右表(table2)其中一个表中存在匹配,则返回行.

FULL OUTER JOIN 关键字结合了 LEFT JOIN 和 RIGHT JOIN 的结果

在这里插入图片描述

性能分析:
大佬博文:https://blog.csdn.net/IT_10/article/details/95916694

建议:尽可能不要使用连接查询(BAT甚至直接禁止在生产环境使用多表连接查询)

原因:

  • 性能太差,上文已经清楚地展示了连接查询的原理
  • 多表查询使逻辑变复杂,难维护,一旦一张表变更,相关连接查询全都死翘翘

通过上面的性能分析我们看出来了连接查询的优缺点。下面我在我们公司的生产环境上随便取了两张发票相关的小表做了性能分析,对比一下直接查询和连接查询:
t_invoice (1067条数据)
t_project_invoice (496条数据)

如下图:
在这里插入图片描述
上图使我们清楚地看到直接查询和连接查询的性能差距

所以,使用单表查询,然后将查询结果在代码中根据业务需要进行处理,是直接有效的方法!!


版权声明:本文为stay_the_course原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。