多表连接
在实际应用中,数据通常分散在多个表中。SQL 的 JOIN 操作允许我们将多个表的数据组合在一起进行查询。本章将详细介绍各种 JOIN 类型及其使用场景。
为什么需要 JOIN?
数据规范化
为了避免数据冗余,我们通常将数据分散到多个表中:
查询关联数据
要查询用户及其订单信息,就需要使用 JOIN:
准备示例数据
创建表
插入数据
数据概览:
users 表:
orders 表:
INNER JOIN(内连接)
基本语法
示例
结果:
注意:赵六没有订单,所以不在结果中。
简写形式
INNER 关键字可以省略:
使用表别名
LEFT JOIN(左连接)
基本语法
示例
结果:
注意:赵六没有订单,但仍然出现在结果中,订单信息为 NULL。
查找没有订单的用户
结果:
RIGHT JOIN(右连接)
基本语法
示例
说明:RIGHT JOIN 返回右表(orders)的所有记录,即使左表(users)中没有匹配的记录。
注意:在实际应用中,LEFT JOIN 更常用,RIGHT JOIN 可以通过调换表的位置用 LEFT JOIN 实现。
FULL OUTER JOIN(全外连接)
基本语法
示例
说明:返回两个表中的所有记录,没有匹配的地方用 NULL 填充。
注意:MySQL 不支持 FULL OUTER JOIN,但可以用 UNION 实现:
CROSS JOIN(交叉连接)
基本语法
示例
说明:返回两个表的笛卡尔积,即每个用户与每个订单的组合。
结果行数:4 个用户 × 4 个订单 = 16 行
使用场景:生成所有可能的组合,如排班表、测试数据等。
SELF JOIN(自连接)
概念
表与自身进行连接,通常用于处理层级关系。
示例:员工和经理
查询员工及其经理:
结果:
多表连接
连接三个表
连接顺序
连接条件
等值连接
非等值连接
多条件连接
使用 WHERE 过滤
在 JOIN 后过滤
JOIN 条件 vs WHERE 条件
区别:
- JOIN 条件中的过滤不影响 LEFT JOIN 返回左表的所有记录
- WHERE 中的过滤会影响最终结果
聚合与 JOIN
统计每个用户的订单数
结果:
性能优化
1. 使用索引
2. 只选择需要的列
3. 先过滤再连接
4. 使用 EXPLAIN 分析
实战示例
示例 1:查询用户订单统计
示例 2:查询最近订单
示例 3:查询高价值客户
常见错误
错误 1:忘记 ON 条件
错误 2:列名歧义
错误 3:混淆 LEFT JOIN 和 INNER JOIN
JOIN 类型对比
小结
本章介绍了 SQL 中的多表连接:
- INNER JOIN:返回两表匹配的记录
- LEFT JOIN:返回左表所有记录,右表没有匹配时返回 NULL
- RIGHT JOIN:返回右表所有记录,左表没有匹配时返回 NULL
- FULL OUTER JOIN:返回两表所有记录
- CROSS JOIN:返回笛卡尔积
- SELF JOIN:表与自身连接
- 多表连接:可以连接多个表
- 性能优化:使用索引、只选择需要的列、先过滤再连接
掌握 JOIN 操作是 SQL 学习的重要里程碑,它让你能够处理复杂的多表查询。
下一步: 学习 子查询,学习如何在查询中嵌套查询。