一、JOIN联合查询(表关联)
通过关联条件横向合并多表数据,扩展查询结果的列信息。
1. 内连接(INNER JOIN)
-
作用 :仅返回两个表中完全匹配的记录,相当于两表的交集。
-
语法:
sqlSELECT 列名 FROM 表1 INNER JOIN 表2 ON 表1.关联列 = 表2.关联列;
-
示例:
sql-- 查询学生及其对应的课程成绩(仅显示有成绩的学生) SELECT s.student_id, s.name, sc.score FROM student s INNER JOIN score sc ON s.student_id = sc.student_id;
-
特点:
-
结果集中不包含任一表的未匹配记录。
-
关联列通常为主键或外键,需确保索引优化。
-
2. 外连接(OUTER JOIN)
保留主表全部记录,从表无匹配时填充NULL
。
2.1 左连接(LEFT JOIN)
-
作用 :以左表为主,返回左表所有记录及右表的匹配记录(无匹配则右表字段为
NULL
)。 -
语法:
sqlSELECT 列名 FROM 表1 LEFT JOIN 表2 ON 表1.关联列 = 表2.关联列;
-
示例:
sql-- 查询所有学生,包括未录入成绩的学生 SELECT s.student_id, s.name, sc.score FROM student s LEFT JOIN score sc ON s.student_id = sc.student_id;
-
结果示例:
student_id name score 1 Alice 90 2 Bob NULL
2.2 右连接(RIGHT JOIN)
-
作用 :以右表为主,返回右表所有记录及左表的匹配记录(无匹配则左表字段为
NULL
)。 -
语法:
sqlSELECT 列名 FROM 表1 RIGHT JOIN 表2 ON 表1.关联列 = 表2.关联列;
-
替代方案:可通过调换表顺序使用左连接实现相同效果。
2.3 全外连接(FULL OUTER JOIN)
-
作用 :返回左右表所有记录,无匹配时填充
NULL
(MySQL需通过UNION
模拟)。 -
语法:
sql(SELECT * FROM 表1 LEFT JOIN 表2 ON 条件) UNION (SELECT * FROM 表1 RIGHT JOIN 表2 ON 条件);
二、UNION联合查询(结果集合并)
纵向合并多个查询结果,要求列数和数据类型一致。
1. UNION
-
作用 :合并结果集并自动去重。
-
语法:
sqlSELECT 列1, 列2 FROM 表A UNION SELECT 列1, 列2 FROM 表B;
-
示例:
sql-- 合并两个班级的学生名单(去重) SELECT name FROM class1 UNION SELECT name FROM class2;
2. UNION ALL
-
作用 :合并结果集并保留所有重复记录 ,性能优于
UNION
。 -
语法:
sqlSELECT 列1, 列2 FROM 表A UNION ALL SELECT 列1, 列2 FROM 表B;
-
示例:
sql-- 合并日志表(保留重复条目) SELECT log_time, message FROM debug_log UNION ALL SELECT log_time, message FROM error_log;
三、核心对比与使用场景
特性 | JOIN | UNION |
---|---|---|
数据方向 | 横向扩展(列合并) | 纵向堆叠(行合并) |
主要用途 | 多表关联查询 | 合并结构相似的结果集 |
去重 | 不自动去重 | UNION 去重,UNION ALL 保留重复 |
性能影响 | 依赖索引和关联条件复杂度 | UNION 需排序去重,性能较低 |
四、最佳实践与注意事项
- 索引优化:
为JOIN
的关联列添加索引(如student_id
),避免全表扫描。
- 避免笛卡尔积:
明确指定ON
条件,否则会返回两表所有行的组合(如表1有10行,表2有20行→200行结果
)。
- 别名简化:
使用表别名提高可读性(如FROM student AS s
)。
- 数据类型匹配:
UNION
要求合并的列数据类型严格一致(如INT
与VARCHAR
不兼容)。
- 分页处理:
对UNION
结果分页时,需在外层包裹子查询:
sql
SELECT * FROM (
SELECT a FROM table1
UNION ALL
SELECT a FROM table2
) AS tmp LIMIT 10 OFFSET 20;
- 性能权衡:
高频查询避免使用UNION
去重,优先考虑业务逻辑去重或UNION ALL
。
五、常见问题解决方案
1.多表关联时的列名冲突:
sql
SELECT s.id AS student_id, c.id AS course_id
FROM student s
JOIN course c ON s.course_id = c.id;
2.关联条件复杂:
使用表别名明确指定列来源。
sql
SELECT *
FROM orders o
JOIN customers c ON o.customer_id = c.id AND c.country = 'USA';
支持多条件AND
/OR
组合。
- 大数据量下的性能问题:
分批次查询或使用临时表减少内存压力。
总结:
-
JOIN用于横向扩展数据,通过关联条件整合多表信息,核心掌握内连接与外连接的区别。
-
UNION用于纵向合并结果集,根据需求选择是否去重。
-
实际开发中:
-
优先使用
LEFT JOIN
确保主表数据完整性。 -
避免不必要的
UNION
去重以提升性能。 -
为高频查询的关联列添加索引。
-
-
通过明确需求、优化查询条件和合理使用索引,可显著提升联合查询效率。