游乐游手机版
首页/数据库/文章详情

MySQL连接查询:内连接、外连接与复合条件详解

时间:2026-07-20 07:00
MySQL连接查询包括内连接、左连接、右连接和复合条件连接。内连接仅返回匹配记录,左连接保留左表全部数据,右连接保留右表全部数据。复合条件连接可在ON或WHERE中追加过滤条件,二者作用不同。需注意关联条件缺失、ON与WHERE混用及表别名规范等常见问题。

前言

在MySQL数据库的多表查询中,连接查询(JOIN) 是一项至关重要的核心技能。它能够将两张甚至多张表中的数据,按照指定的关联关系进行整合,形成一张完整的虚拟结果集。本文将以一张核心知识图谱为主线,从语法结构、适用场景、代码示例三个维度,全面解析MySQL连接查询的各类操作。

Mysql连接查询之内连接、外连接与复合条件查询完全解析

一、核心知识点总览

在动手编写SQL语句之前,我们先梳理清楚几种连接类型的基本概念。下表归纳了它们的关键逻辑和语法特点:

连接类型语法核心逻辑结果特点
内连接(INNER JOIN)A INNER JOIN B ON 关联条件仅返回两张表中匹配成功的记录无匹配数据不显示
左连接(LEFT JOIN)A LEFT JOIN B ON 关联条件左表 A 为主,匹配右表 B;左表全部显示,右表无匹配则填充 NULL左表数据完整,右表按需补空
右连接(RIGHT JOIN)A RIGHT JOIN B ON 关联条件右表 B 为主,匹配左表 A;右表全部显示,左表无匹配则填充 NULL右表数据完整,左表按需补空
复合条件连接连接查询 + 多条件过滤在连接基础上,追加 WHERE/ON 多条件筛选精准过滤关联数据

二、准备测试数据

理论知识需要结合实践才能深入理解,接下来我们创建两张表,将所有示例完整执行一遍。

1. 学生表student(左表)

CREATE TABLE score (    score_id INT PRIMARY KEY AUTO_INCREMENT,    stu_id INT NOT NULL,    subject VARCHAR(20) NOT NULL,    score INT NOT NULL,    FOREIGN KEY (stu_id) REFERENCES student(stu_id));INSERT INTO score (stu_id, subject, score) VALUES(1, '语文', 85),(1, '数学', 92),(2, '语文', 78),(3, '数学', 88); -- 赵六(stu_id=4)无成绩

2. 成绩表score(右表)

CREATE TABLE score (    score_id INT PRIMARY KEY AUTO_INCREMENT,    stu_id INT NOT NULL,    subject VARCHAR(20) NOT NULL,    score INT NOT NULL,    FOREIGN KEY (stu_id) REFERENCES student(stu_id));INSERT INTO score (stu_id, subject, score) VALUES(1, '语文', 85),(1, '数学', 92),(2, '语文', 78),(3, '数学', 88); -- 赵六(stu_id=4)无成绩

三、各连接类型详解 + 代码示例

1. 内连接查询(INNER JOIN)

核心逻辑

内连接是日常开发中使用频率最高的连接方式,仅返回两张表中满足关联条件的记录,可以理解为“取两张表的交集”。

  • 等价语法:SELECT * FROM A,B WHERE A.id = B.id(隐式内连接)
  • 标准语法:SELECT * FROM A INNER JOIN B ON A.id = B.id(显式内连接,推荐使用)

代码示例

-- 显式内连接:查询有成绩的学生信息+成绩SELECT     s.stu_id, s.stu_name, s.class,     sc.subject, sc.scoreFROM student sINNER JOIN score sc     ON s.stu_id = sc.stu_id;

运行结果

stu_idstu_nameclasssubjectscore
1张三一班语文85
1张三一班数学92
2李四二班语文78
3王五一班数学88

说明

  • 赵六(stu_id=4)因为在成绩表中没有对应的记录,所以内连接的结果中不会出现——这正体现了“无匹配不显示”的特性。

2. 外连接查询

外连接与内连接的区别在于,它以某一张表为基准,保留基准表的所有数据,另一张表有匹配则显示,无匹配则填充 NULL。具体分为左连接右连接

(1)左连接(LEFT JOIN)

核心逻辑

左表为基准,左表的全部记录都会出现在结果集中,右表有匹配则显示数据,否则填充 NULL

  • 语法:A LEFT JOIN B ON 关联条件(A 是左表,B 是右表)

代码示例

-- 左连接:以学生表为基准,查询所有学生(含无成绩的赵六)SELECT     s.stu_id, s.stu_name, s.class,     sc.subject, sc.scoreFROM student sLEFT JOIN score sc     ON s.stu_id = sc.stu_id;

运行结果

stu_idstu_nameclasssubjectscore
1张三一班语文85
1张三一班数学92
2李四二班语文78
3王五一班数学88
4赵六三班NULLNULL

说明

  • 左表(学生表)中的所有学生都显示出来,赵六也没有被遗漏。但由于他没有成绩记录,因此右表的相关字段填充了 NULL

(2)右连接(RIGHT JOIN)

核心逻辑

右表为基准,右表全部记录都显示,左表匹配到则显示,否则填充 NULL

  • 语法:A RIGHT JOIN B ON 关联条件(B 是右表,A 是左表)
  • 实际上,A LEFT JOIN BB RIGHT JOIN A 是等价的。在日常开发中,优先使用左连接,因为代码可读性更好。

代码示例

-- 右连接:以成绩表为基准,查询所有成绩(本例中成绩表所有记录都能匹配到学生)SELECT     s.stu_id, s.stu_name, s.class,     sc.subject, sc.scoreFROM student sRIGHT JOIN score sc     ON s.stu_id = sc.stu_id;

运行结果

与内连接结果完全一致——因为成绩表里的所有记录都能在学生表中找到对应的学生。

3. 复合条件连接查询

核心逻辑

在连接查询的基础上,叠加多个过滤条件,实现更精准的数据筛选。条件可以写在 ON 子句中(在连接时过滤),也可以写在 WHERE 子句中(连接完成后过滤)。

代码示例 1:连接 + 单条件过滤

-- 左连接+WHERE:查询一班所有学生(含无成绩的)SELECT     s.stu_id, s.stu_name, s.class,     sc.subject, sc.scoreFROM student sLEFT JOIN score sc     ON s.stu_id = sc.stu_idWHERE s.class = '一班';

运行结果

stu_idstu_nameclasssubjectscore
1张三一班语文85
1张三一班数学92
3王五一班数学88

代码示例 2:多条件复合连接

-- 左连接+多条件:查询一班成绩>80的学生,无成绩也显示SELECT     s.stu_id, s.stu_name, s.class,     sc.subject, sc.scoreFROM student sLEFT JOIN score sc     ON s.stu_id = sc.stu_id     AND sc.score > 80  -- 连接时过滤成绩>80WHERE s.class = '一班'; -- 过滤班级

运行结果

stu_idstu_nameclasssubjectscore
1张三一班数学92
3王五一班数学88

关键说明:ON与WHERE的区别

  • ON 子句:连接时过滤,只影响右表的匹配结果,不影响左表是否显示(左表仍然全显)
  • WHERE 子句:连接后过滤,是对最终结果集的筛选,不符合条件的行直接删除

这个区别在实际开发中非常关键,需要特别留意:查询条件放错位置,结果可能天差地别。

四、核心对比与避坑指南

1. 内连接 vs 外连接 核心区别

场景推荐连接原因
只需要匹配成功的数据内连接结果最精简,性能最优
需要保留左表所有数据左连接左表完整,右表补空
需要保留右表所有数据右连接可转换为左连接,优先用左连接

2. 常见避坑

1.关联条件缺失:多表连接必须加 ON 关联条件,否则会产生笛卡尔积(数据爆炸)

-- 错误!无关联条件,笛卡尔积SELECT * FROM student, score;

2.ONWHERE 混用:外连接中,WHERE 会过滤左表数据,导致外连接失效

-- 错误!WHERE sc.score>80 会过滤掉赵六的NULL行,左连接变内连接SELECT * FROM student s LEFT JOIN score sc ON s.stu_id=sc.stu_id WHERE sc.score>80;

3.表别名不规范:多表同名字段必须加表别名,否则报错

-- 错误!stu_id 不明确属于哪个表SELECT stu_id FROM student s JOIN score sc ON s.stu_id=sc.stu_id;-- 正确:加表别名SELECT s.stu_id FROM student s JOIN score sc ON s.stu_id=sc.stu_id;

五、综合实战:多表连接 + 复合条件

-- 需求:查询所有学生的总分,无成绩的学生总分显示0,按班级分组SELECT     s.class,    s.stu_name,    IFNULL(SUM(sc.score), 0) AS total_score  -- IFNULL 把NULL转为0FROM student sLEFT JOIN score sc     ON s.stu_id = sc.stu_idGROUP BY s.stu_id, s.stu_name, s.classORDER BY total_score DESC;

运行结果

classstu_nametotal_score
一班张三177
一班王五88
二班李四78
三班赵六0

六、核心总结

  1. 内连接:取交集,仅显示匹配数据
  2. 左连接:左表全显,右表补空;右连接:右表全显,左表补空
  3. 复合条件ON 过滤连接,WHERE 过滤结果,不可混用
  4. 避坑关键:必须加关联条件,同名字段加别名,外连接慎用 WHERE 过滤
  5. 性能优化:大表连接优先用内连接,关联字段加索引,避免笛卡尔积
来源:https://www.jb51.net/database/367203zko.htm
上一篇Redis管道技术加速雪崩后缓存预热批量入库 下一篇MySQL主从复制与GTID环形复制代码实例
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
为什么SQL中 NOT IN 子查询遇到 NULL 会导致 JOIN 逻辑完全崩溃失效
数据库 · 2026-07-21

为什么SQL中 NOT IN 子查询遇到 NULL 会导致 JOIN 逻辑完全崩溃失效

SQL的NOTIN子查询若结果包含NULL,三值逻辑会使整行判断为UNKNOWN,WHERE仅保留TRUE,导致所有行被过滤,返回空集。推荐使用NOTEXISTS替代,它不比较值,只判断子查询是否返回行,天然规避NULL问题。LEFTJOIN+ISNULL易写错,COALESCE或加ISNOTNULL仅权宜之计,可能掩盖数据问题。

完整Redis集群架构图及搭建步骤详解,新手必看
数据库 · 2026-07-21

完整Redis集群架构图及搭建步骤详解,新手必看

一、简介 Redis集群功能从3 0版本开始引入,到5 0 14版本已经相当成熟。本文就来聊聊如何搭建一个最简单的集群,以及常用的集群管理命令。版本锁定在5 0 14,所有操作均基于此版本。 二、架构图 先来看一个最基础的集群架构,一目了然: 三、搭建集群 3 1、下载 这里是在一台Linux服务器

SQL存储过程结合XML数据类型的高性能解析技巧
数据库 · 2026-07-21

SQL存储过程结合XML数据类型的高性能解析技巧

直接用 nodes() + value(),别碰 OPENXML 从 SQL Server 2005 起,OPENXML 就应该被淘汰了。它需要手动调用 sp_xml_preparedocument 和 sp_xml_removedocument,一旦遗漏后者就会引发内存泄漏;而且整个过程基于临

SQL窗口函数生成带层级结构的财务流水号技巧
数据库 · 2026-07-21

SQL窗口函数生成带层级结构的财务流水号技巧

财务流水号按业务类型分组连续编号,需用ROW_NUMBER()OVER(PARTITIONBYbusiness_typeORDERBYcreate_time)生成,避免先GROUPBY致明细丢失。日期前缀和补零拼接需注意数据库差异。多级嵌套结构需在PARTITIONBY中增加额外分类字段,并发环境下窗口函数无法保证唯一性,需结合序列或锁机制。

SQL中COALESCE函数优雅处理NULL值技巧与最佳实践全面指南
数据库 · 2026-07-21

SQL中COALESCE函数优雅处理NULL值技巧与最佳实践全面指南

COALESCE函数从左到右返回首个非NULL值,参数顺序决定兜底是否生效;类型不兼容时PostgreSQL和SQLServer报错,需显式CAST对齐;运算前需对每个可能为NULL的项单独包裹,否则表达式整体为NULL;避免在WHERE或JOIN条件中使用,否则导致语义错乱或索引失效;不处理空字符串,需嵌套NULLIF。