MySQL联合查询

一、JOIN联合查询(表关联)

通过关联条件横向合并多表数据,扩展查询结果的列信息。

1. 内连接(INNER JOIN)
  • 作用 :仅返回两个表中完全匹配的记录,相当于两表的交集。

  • 语法:

    sql 复制代码
    SELECT 列名  
    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)。

  • 语法:

    sql 复制代码
    SELECT 列名  
    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)。

  • 语法:

    sql 复制代码
    SELECT 列名  
    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
  • 作用 :合并结果集并自动去重。

  • 语法:

    sql 复制代码
    SELECT 列1, 列2 FROM 表A  
    UNION  
    SELECT 列1, 列2 FROM 表B;  
  • 示例:

    sql 复制代码
    -- 合并两个班级的学生名单(去重)  
    SELECT name FROM class1  
    UNION  
    SELECT name FROM class2;  
2. UNION ALL
  • 作用 :合并结果集并保留所有重复记录 ,性能优于UNION。

  • 语法:

    sql 复制代码
    SELECT 列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去重以提升性能。

    • 为高频查询的关联列添加索引。

  • 通过明确需求、优化查询条件和合理使用索引,可显著提升联合查询效率。

相关推荐
PaperData35 分钟前
1985-2025年全国区县专利申请与授权面板数据
数据库
snpgroupcn38 分钟前
大数据量SAP迁移方案:系统越大,越不能硬搬
数据库·sap
Flynt2 小时前
Redis Cluster主节点挂了,为什么"高可用"还全员掉线?我把三次kill的记录翻出来了
数据库·redis·分布式
笃行3502 小时前
KingbaseES 数据加密全解:从 SSL 到全密态
数据库
Ivanqhz2 小时前
激活函数在 Transformer 中的作用及各种变体简述
java·linux·数据库·人工智能·深度学习
java1234_小锋3 小时前
【技术专题】Mysql8 数据库 - Mysql8 数据类型简介
数据库·mysql
知行EDI4 小时前
知行之桥 MaBang 端口使用指南——Create Order 订单创建篇
java·服务器·数据库
成旭先生4 小时前
【2026】企业信息模糊查询 API 实战:名称、注册号、统一社会信用代码、企业类型与法人一次查全
服务器·数据库·数据服务
JosieBook4 小时前
【数据库】MySQL 实战精通系列 · 第10篇:分库分表与分布式事务实战
数据库·分布式·mysql
我叫洋洋5 小时前
Cadence CIS 元器件库合并实战:3000+ 焊盘、156 个符号零冲突并入自有库
数据库·单片机·嵌入式硬件·oracle·电路