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

相关推荐
woxihuan1234561 分钟前
CSS移动端实现响应式导航菜单_利用媒体查询切换显示隐藏状态
jvm·数据库·python
Aaa111114432 分钟前
四类地址 逻辑地址 线性地址 虚拟地址 物理地址
java
小则又沐风a2 分钟前
深入了解进程概念 第二章
java·linux·服务器·前端
CCPC不拿奖不改名2 分钟前
PostgreSQL数据库部署linux服务器流程
linux·服务器·数据库·windows·python·docker·postgresql
沐知全栈开发4 分钟前
AngularJS 简介
开发语言
程序猿进阶5 分钟前
OpenClaw Mac 安装教程
java·macos·ai·架构·agent·openclaw
彳亍1015 分钟前
mysql如何通过mysqldump备份视图与触发器_使用相关参数
jvm·数据库·python
重生之小比特6 分钟前
【MySQL 数据库】用户管理与权限控制
android·数据库·mysql
ZC跨境爬虫7 分钟前
跟着 MDN 学 HTML day_60:(表单与按钮技能测试实战)
服务器·前端·javascript·数据库·ui·html
骑士雄师12 分钟前
学生管理系统python版本比对
开发语言·python