外连接类型对比
连接类型 | 关键字 | 保留表 | 结果特点 |
---|---|---|---|
左外连接 | LEFT [OUTER] JOIN | 左表 | 包含左表所有记录 + 右表匹配记录 |
右外连接 | RIGHT [OUTER] JOIN | 右表 | 包含右表所有记录 + 左表匹配记录 |
全外连接 | FULL [OUTER] JOIN | 两表 | MySQL不直接支持,需用UNION实现 |
左外连接(LEFT JOIN)
基本语法
SELECT 字段列表
FROM 左表
LEFT [OUTER] JOIN 右表 ON 连接条件
[WHERE 其他条件];
特点解析
1. 返回左表所有记录,即使右表没有匹配
2. 右表无匹配时显示为NULL
3. OUTER关键字可省略
实际案例
查询所有学生及其课程(包括没选课的学生)
SELECT s.name, c.course_name FROM students s LEFT JOIN courses c ON s.course_id = c.id;
特殊应用
查找没有选课的学生(利用NULL判断)
SELECT s.name FROM students s LEFT JOIN courses c ON s.course_id = c.id WHERE c.id IS NULL;
右外连接(RIGHT JOIN)
基本语法
SELECT 字段列表
FROM 左表
RIGHT [OUTER] JOIN 右表 ON 连接条件
[WHERE 其他条件];
特点解析
1. 返回右表所有记录,即使左表没有匹配
2. 左表无匹配时显示为NULL
3. 可视为左连接的反向操作
实际案例
查询所有课程及其学生(包括没有学生的课程)
SELECT c.course_name, s.name FROM students s RIGHT JOIN courses c ON s.course_id = c.id;
全外连接(FULL JOIN)模拟
MySQL不直接支持FULL JOIN,但可通过UNION实现:
模拟全外连接
SELECT s.name, c.course_name FROM students s LEFT JOIN courses c ON s.course_id = c.id UNION SELECT s.name, c.course_name FROM students s RIGHT JOIN courses c ON s.course_id = c.id WHERE s.id IS NULL;
性能优化建议
1. 索引优化:确保连接字段有索引
2. 小表驱动:LEFT JOIN时小表放左边
3. 避免过度使用:只在需要保留不匹配记录时使用
4. 替代方案:考虑先内连接再UNION缺失记录
多表外连接示例
学生-课程-教师三级外连接
SELECT s.name, c.course_name, t.teacher_name FROM students s LEFT JOIN courses c ON s.course_id = c.id LEFT JOIN teachers t ON c.teacher_id = t.id;
实际业务场景
场景1:报表统计
统计各部门员工数(包括无员工的部门)
SELECT d.dept_name, COUNT(e.id) AS employee_count FROM departments d LEFT JOIN employees e ON d.id = e.dept_id GROUP BY d.dept_name;
场景2:订单分析
查找从未下单的客户
SELECT c.customer_name FROM customers c LEFT JOIN orders o ON c.id = o.customer_id WHERE o.id IS NULL;
场景3:课程管理
显示所有课程及选修人数(包括无人选修的课程)
SELECT c.course_name, COUNT(s.id) AS student_count FROM courses c LEFT JOIN students s ON c.id = s.course_id GROUP BY c.course_name;
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程