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要求合并的列数据类型严格一致(如INTVARCHAR不兼容)。

  • 分页处理

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去重以提升性能。

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

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

相关推荐
0xDevNull4 小时前
MySQL数据冷热分离详解
后端·mysql
科技小花4 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸4 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain4 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希5 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神5 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员5 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java5 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿5 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴5 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存