SQL表连接

想象你手上有两张表:

示例数据

员工表 Employees

复制代码
员工ID  | 姓名    | 部门ID
--------|---------|--------
1       | 张三    | 10
2       | 李四    | 20
3       | 王五    | 30
4       | 赵六    | NULL

部门表 Departments

复制代码
部门ID  | 部门名称
--------|----------
10      | 技术部
20      | 销售部
50      | 人事部

1. **INNER JOIN(内连接)**​ - 只要"匹配的"

inner可以省略

复制代码
SELECT e.姓名, d.部门名称
FROM Employees e
INNER JOIN Departments d ON e.部门ID = d.部门ID;

结果

复制代码
姓名    | 部门名称
--------|----------
张三    | 技术部
李四    | 销售部

解释 :只返回两张表都有匹配的记录。王五(部门ID=30)和赵六(部门ID=NULL)没有匹配的部门,所以不显示。


2. **LEFT JOIN(左连接)**​ - "左边的全要,右边的能配上就配"

复制代码
SELECT e.姓名, d.部门名称
FROM Employees e
LEFT JOIN Departments d ON e.部门ID = d.部门ID;

结果

复制代码
姓名    | 部门名称
--------|----------
张三    | 技术部
李四    | 销售部
王五    | NULL      ← 部门ID=30没找到
赵六    | NULL      ← 部门ID=NULL

解释 :以**左表(Employees)**为主,左表所有记录都显示,右表匹配不上就显示NULL。


3. **RIGHT JOIN(右连接)**​ - "右边的全要,左边的能配上就配"

复制代码
SELECT e.姓名, d.部门名称
FROM Employees e
RIGHT JOIN Departments d ON e.部门ID = d.部门ID;

结果

复制代码
姓名    | 部门名称
--------|----------
张三    | 技术部
李四    | 销售部
NULL    | 人事部    ← 部门ID=50没员工

解释 :以**右表(Departments)**为主,右表所有记录都显示,左表匹配不上就显示NULL。


4. **FULL JOIN(全连接)**​ - "我全都要"

复制代码
SELECT e.姓名, d.部门名称
FROM Employees e
FULL JOIN Departments d ON e.部门ID = d.部门ID;

结果

复制代码
姓名    | 部门名称
--------|----------
张三    | 技术部
李四    | 销售部
王五    | NULL      ← 员工有,部门无
赵六    | NULL      ← 员工有,部门无
NULL    | 人事部    ← 部门有,员工无

解释:左右表所有记录都显示,匹配不上就用NULL补全。


5. **CROSS JOIN(交叉连接)**​ - "所有组合"

复制代码
SELECT e.姓名, d.部门名称
FROM Employees e
CROSS JOIN Departments d;

结果:4个员工 × 3个部门 = 12行

复制代码
姓名    | 部门名称
--------|----------
张三    | 技术部
张三    | 销售部
张三    | 人事部
李四    | 技术部
李四    | 销售部
李四    | 人事部
...     | ...

ON 条件怎么理解?

ON条件就像是连接条件,告诉数据库怎么把两表的行"配对"。

例子1:等值连接(最常用)

复制代码
ON e.部门ID = d.部门ID

把员工表的部门ID和部门表的部门ID相等的行连在一起。

例子2:不等连接

复制代码
ON e.工资 > d.最低工资

连接那些员工工资大于部门最低工资的行。

例子3:多条件连接

复制代码
ON e.部门ID = d.部门ID 
   AND e.入职日期 > '2020-01-01'

既要部门ID相等,又要员工是2020年以后入职的。


JOIN 执行顺序可视化

复制代码
FROM 左表
LEFT JOIN 右表 ON 连接条件
WHERE 过滤条件

重要区别

  • ON:连接时的匹配条件(决定怎么连)

  • WHERE:连接后的过滤条件(决定显示哪些)

示例对比:

复制代码
-- ON 影响连接结果
SELECT * 
FROM A LEFT JOIN B 
ON A.id = B.id AND B.status = 'active';
-- 先按条件连接,再显示所有A的记录

-- WHERE 在连接后过滤  
SELECT *
FROM A LEFT JOIN B ON A.id = B.id
WHERE B.status = 'active';
-- 先连接,然后过滤掉B.status不是active的行
-- 注意:这会把B为NULL的行也过滤掉!

记忆口诀

  • INNER JOIN:只要"配对的"

  • LEFT JOIN:左表全要,右边"爱配不配"

  • RIGHT JOIN:右表全要,左边"爱配不配"

  • FULL JOIN:两个全要,"不配就NULL"

  • ON:是"介绍人",负责两边怎么认识

  • WHERE:是"家长",见面后还要筛选

实战建议

  1. 大部分情况用 LEFT JOIN(以主表为基准)

  2. 明确知道只要交集用 INNER JOIN

  3. ON条件尽量用索引字段(如ID)

  4. 复杂的过滤放WHERE,简单的匹配放ON

相关推荐
数智化管理手记6 小时前
精益生产中的TPM管理是什么?一文破解设备零故障的密码
服务器·网络·数据库·低代码·制造·源代码管理·精益工程
翊谦6 小时前
Java Agent开发 Milvus 向量数据库安装
java·数据库·milvus
晓晓hh6 小时前
JavaSE学习——迭代器
java·开发语言·学习
Laurence6 小时前
C++ 引入第三方库(一):直接引入源文件
开发语言·c++·第三方库·添加·添加库·添加包·源文件
查古穆6 小时前
栈-有效的括号
java·数据结构·算法
kyriewen117 小时前
你点的“刷新”是假刷新?前端路由的瞒天过海术
开发语言·前端·javascript·ecmascript·html5
Java面试题总结7 小时前
Spring - Bean 生命周期
java·spring·rpc
硅基诗人7 小时前
每日一道面试题 10:synchronized 与 ReentrantLock 的核心区别及生产环境如何选型?
java
014-code7 小时前
String.intern() 到底干了什么
java·开发语言·面试
難釋懷7 小时前
OpenResty实现Redis查询
数据库·redis·openresty