SELECT 字段列表
FROM 左表 [AS] 别名1
LEFT JOIN 右表 [AS] 别名2
ON 别名1.关联字段 = 别名2.关联字段
[WHERE 过滤条件];
2.2.3 实战示例
sql复制代码
-- 需求:查询所有学生信息,及对应班级信息(无班级的学生也需显示)
SELECT
s.id AS student_id,
s.student_name,
c.id AS class_id,
c.class_name,
c.grade
FROM student s -- 左表:学生表(保留所有学生)
LEFT JOIN class c -- 右表:班级表
ON s.class_id = c.id;
等价转换:A RIGHT JOIN B 可转换为 B LEFT JOIN A(推荐用LEFT JOIN,更符合阅读习惯)。
2.3.2 语法结构
sql复制代码
SELECT 字段列表
FROM 左表 [AS] 别名1
RIGHT JOIN 右表 [AS] 别名2
ON 别名1.关联字段 = 别名2.关联字段
[WHERE 过滤条件];
2.3.3 实战示例
sql复制代码
-- 需求:查询所有班级信息,及对应学生信息(无学生的班级也需显示)
SELECT
s.id AS student_id,
s.student_name,
c.id AS class_id,
c.class_name,
c.grade
FROM student s -- 左表:学生表
RIGHT JOIN class c -- 右表:班级表(保留所有班级)
ON s.class_id = c.id;
数据库支持:Oracle、SQL Server原生支持;MySQL无原生FULL JOIN,需通过LEFT JOIN + UNION ALL + RIGHT JOIN模拟。
2.4.2 语法结构
(1)原生语法(Oracle/SQL Server)
sql复制代码
SELECT 字段列表
FROM 表1 [AS] 别名1
FULL JOIN 表2 [AS] 别名2
ON 别名1.关联字段 = 别名2.关联字段;
(2)MySQL模拟语法
sql复制代码
-- 步骤1:左连接获取左表全量+右表匹配
SELECT 字段列表 FROM 表1 LEFT JOIN 表2 ON 关联条件
UNION ALL
-- 步骤2:右连接获取右表无匹配的行(过滤重复)
SELECT 字段列表 FROM 表1 RIGHT JOIN 表2 ON 关联条件 WHERE 表1.主键 IS NULL;
2.4.3 实战示例(MySQL模拟)
sql复制代码
-- 需求:查询所有学生 + 所有班级,无匹配的字段显示NULL
-- 步骤1:左连接(所有学生 + 匹配班级)
SELECT
s.id AS student_id,
s.student_name,
c.id AS class_id,
c.class_name,
c.grade
FROM student s
LEFT JOIN class c ON s.class_id = c.id
UNION ALL -- 合并结果(无去重,效率高于UNION)
-- 步骤2:右连接获取班级无学生的行
SELECT
s.id AS student_id,
s.student_name,
c.id AS class_id,
c.class_name,
c.grade
FROM student s
RIGHT JOIN class c ON s.class_id = c.id
WHERE s.id IS NULL; -- 过滤掉已在左连接中返回的行
2.4.4 执行结果
student_id
student_name
class_id
class_name
grade
1
张三
1
一班
一年级
2
李四
1
一班
一年级
3
王五
2
二班
一年级
4
赵六
NULL
NULL
NULL
5
钱七
NULL
NULL
NULL
NULL
NULL
3
三班
一年级
NULL
NULL
4
四班
一年级
2.4.5 优缺点
优点
缺点
覆盖所有数据场景,无遗漏
执行效率低(需处理全量数据+合并结果)
适合数据对账,识别所有不匹配记录
MySQL需模拟,SQL复杂度高
2.4.6 适用场景
数据全量对账(如"核对所有订单 + 所有支付记录,识别未匹配的订单/支付");
无过滤的全量数据整合(如"导出所有商品 + 所有库存记录")。
2.5 交叉连接(CROSS JOIN)
2.5.1 核心原理
返回两张表的笛卡尔积,即左表每一行与右表每一行组合,结果行数 = 左表行数 × 右表行数。
触发条件:显式写CROSS JOIN,或无ON条件的JOIN(如SELECT * FROM student, class)。
2.5.2 语法结构
sql复制代码
-- 显式写法(推荐,语义清晰)
SELECT 字段列表 FROM 表1 CROSS JOIN 表2;
-- 隐式写法(无ON条件,不推荐)
SELECT 字段列表 FROM 表1, 表2;
2.5.3 实战示例
sql复制代码
-- 需求:生成学生表(5行)× 班级表(4行)的笛卡尔积(共20行)
SELECT
s.id AS student_id,
s.student_name,
c.id AS class_id,
c.class_name
FROM student s
CROSS JOIN class c; -- 无ON条件,直接组合所有行
SELECT 字段列表
FROM 表 [AS] 别名1
JOIN 表 [AS] 别名2 -- 内/左/右连接均可
ON 别名1.关联字段 = 别名2.主键字段;
2.6.3 实战示例(扩展学生表为层级结构)
sql复制代码
-- 步骤1:扩展学生表,新增"同桌ID"字段(关联自身id)
ALTER TABLE student ADD deskmate_id INT COMMENT '同桌ID(关联student.id)';
UPDATE student SET deskmate_id = 2 WHERE id = 1; -- 张三同桌是李四
UPDATE student SET deskmate_id = 1 WHERE id = 2; -- 李四同桌是张三
UPDATE student SET deskmate_id = NULL WHERE id IN (3,4,5); -- 其他学生无同桌
-- 步骤2:自连接查询学生及同桌信息
SELECT
t1.id AS student_id,
t1.student_name,
t2.id AS deskmate_id,
t2.student_name AS deskmate_name
FROM student t1 -- 主表:学生
LEFT JOIN student t2 -- 自连接:同桌(别名t2)
ON t1.deskmate_id = t2.id; -- 关联条件:自身的同桌ID = 另一行的学生ID