大家好,我是刚子。
面试的时候,SQL JOIN 几乎是必考题。Inner Join、Left Join、Right Join、Full Join,还有 On 和 Where 的区别,你能说清楚吗?
很多初学者一看就晕,今天刚子用最直白的方式给你讲明白。咱们直接上例子,看完你就会了。
先看两张表
我们有两张表:学生表(Students) 和 班级表(Class)。
Students 表:

Class 表:

一、JOIN 和 INNER JOIN(内连接)
概念:只返回两张表里能匹配上的数据。匹配不上的,一概不要。
两种写法,结果一样:
-- 老式写法(用 where)
select * from Students s, Class c where s.ClassId = c.ClassId
-- 标准写法(用 inner join)
select * from Students s inner join Class c on s.ClassId = c.ClassId
结果:

划重点:Inner Join 就是“找对象”,你俩得有共同点(ClassId 对得上)才能出现在结果里。单身的不要,没人的班也不要。
二、LEFT JOIN(左连接)
概念:以左边的表为主,左边表的所有数据全部返回。右边表能匹配上的就带上,匹配不上的填 NULL。
select * from Students s left join Class c on s.ClassId = c.ClassId
结果:

划重点:Left Join 就是“左表全保留,右表能配就配,配不上拉倒填 NULL”。记住:LEFT 左边全保留。
三、RIGHT JOIN(右连接)
概念:跟 Left Join 反过来,以右边的表为主,右边表的所有数据全部返回。左边表能匹配上的就带上,匹配不上的填 NULL。
select * from Students s right join Class c on s.ClassId = c.ClassId
结果:

划重点:Right Join 用得少,因为你可以把表换个位置写成 Left Join。比如上面的 right join 改成 from Class c left join Students s 效果一样。你记住 Left 就够了,Right 了解概念就行。
四、FULL JOIN(全连接)
概念:左表和右表的所有数据全返回。能匹配上的就拼在一起,匹配不上的那一半填 NULL。
select * from Students s full join Class c on s.ClassId = c.ClassId
结果:

划重点:Full Join 就是“大团圆”,你俩不管配不配得上,全都给我出来。用得不多,但面试可能会问。
五、ON 和 WHERE 的区别(重点!)
这是面试最爱问的,也是新手最容易翻车的。
一句话记住:
- ON:在生成临时表的时候起作用。
- WHERE:在临时表生成之后,对结果再过滤。
听起来抽象?刚子给你举个例子就懂了。
先看 INNER JOIN 的情况
-- 用 ON 加条件
select * from Students s inner join Class c on s.ClassId = c.ClassId and s.Sex = '男'
结果:只返回男生且能匹配上班级的学生。

-- 用 WHERE 加条件
select * from Students s inner join Class c on s.ClassId = c.ClassId where s.Sex = '男'
结果:一模一样。
结论:对于 INNER JOIN,ON 和 WHERE 效果一样。因为 inner join 只保留匹配上的记录,过滤条件放哪里没区别。
再看 LEFT JOIN 的情况(关键!)
-- 条件放在 ON 里
select * from Students s left join Class c on s.ClassId = c.ClassId and s.Sex = '男'
结果:左表所有学生都出来,但只有男生才会去匹配班级。女生和没分班的仍然出现,但右边班级信息是 NULL。

-- 条件放在 WHERE 里
select * from Students s left join Class c on s.ClassId = c.ClassId where s.Sex = '男'
结果:先做左连接(所有学生都在),然后用 where s.Sex = '男' 过滤。
看出区别了吗?
- ON 里的条件只影响“怎么匹配右表”,但左表记录一条不少。
- WHERE 里的条件是最终过滤,左表记录也可能被删掉。
刚子大白话:
- 用 LEFT JOIN 时,ON 里面的条件不会干掉左表的行,它只是决定右表带什么数据过来。
- 而 WHERE 是冷酷无情的过滤器,不符合条件的行,管你左表右表,全删。
总结(面试背这个)
| 连接类型 | 作用 |
|---|---|
| INNER JOIN | 只返回两张表能匹配上的行 |
| LEFT JOIN | 左表全返回,右表能配就配,配不上填 NULL |
| RIGHT JOIN | 右表全返回,左表能配就配,配不上填 NULL |
| FULL JOIN | 两张表全返回,能配就配,配不上填 NULL |
| 关键字 | 作用时机 | 对 LEFT JOIN 的影响 |
|---|---|---|
| ON | 生成临时表时,决定如何匹配 | 不会过滤左表记录 |
| WHERE | 临时表生成后,最终过滤 | 会过滤掉任何不满足条件的行(包括左表) |
刚子送你一句话:写 LEFT JOIN 的时候,把过滤条件想清楚——你是想限制右表带什么(放 ON),还是想最终干掉某些左表行(放 WHERE)。搞反了,数据就对不上了。
如果你觉得这篇文章有用,点个赞、转给还在被 JOIN 折磨的兄弟。
我是刚子,一个还在写 SQL 的.NET老程序员。咱们下回见!