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

MySQL JOIN 多表查询实战:INNER、LEFT 与 RIGHT 连接详解

时间:2026-08-31 11:47
本文详解 MySQL 中 INNER JOIN、LEFT JOIN 和 RIGHT JOIN 的核心用法与区别。通过具体 SQL 语法、表别名应用、多表连接及过滤条件示例,结合命令行与 PHP 脚本实战,帮助开发者掌握高效的多表数据联合查询技巧。

本文详解 MySQL 中 INNER JOIN、LEFT JOIN 和 RIGHT JOIN 的核心用法与区别。通过具体 SQL 语法、表别名应用、多表连接及过滤条件示例,结合命令行与 PHP 脚本实战,帮助开发者掌握高效的多表数据联合查询技巧。

MySQL JOIN 查询结果预览

在使用 MySQL 进行多表查询时,JOIN 语句能够根据指定的连接条件将多个表的数据关联在一起。以下是三种主要 JOIN 类型在典型场景下的输出效果对比:

MySQL INNER JOIN 执行结果,显示两个表中匹配字段的关联数据
INNER JOIN 执行结果:仅返回两个表中匹配字段的数据,未匹配的记录被过滤。
MySQL LEFT JOIN 执行结果,左侧表所有记录保留,右侧无匹配字段显示为 NULL
LEFT JOIN 执行结果:保留左表所有记录,右表无匹配时对应字段显示为 NULL。
MySQL RIGHT JOIN 执行结果,右侧表所有记录保留,左侧无匹配字段显示为 NULL
RIGHT JOIN 执行结果:保留右表所有记录,左表无匹配时对应字段显示为 NULL。

前置准备:数据库与表结构

为了演示 JOIN 的实际应用,我们需要准备两个基础数据表:tcount_tbl(存储作者及其登录次数)和 runoob_tbl(存储教程信息)。以下是测试数据的初始化语句:

mysql> use RUNOOB;
Database changed
mysql> SELECT * FROM tcount_tbl;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| 菜鸟教程  | 10           |
| RUNOOB.COM    | 20           |
| Google        | 22           |
+---------------+--------------+
3 rows in set (0.01 sec)

mysql> SELECT * from runoob_tbl;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title  | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 1         | 学习 PHP    | 菜鸟教程  | 2017-04-12      |
| 2         | 学习 MySQL  | 菜鸟教程  | 2017-04-12      |
| 3         | 学习 Java   | RUNOOB.COM    | 2015-05-01      |
| 4         | 学习 Python | RUNOOB.COM    | 2016-03-06      |
| 5         | 学习 C      | FK            | 2017-04-05      |
+-----------+---------------+---------------+-----------------+
5 rows in set (0.01 sec)

接下来,我们将基于这两张表,分别演示 INNER JOIN、LEFT JOIN 和 RIGHT JOIN 的具体操作。

第一步:使用 INNER JOIN 获取匹配数据

INNER JOIN(内连接)是最常用的连接类型,它只返回两个表中字段匹配关系的记录。如果某条记录在另一个表中没有匹配项,该记录将不会出现在结果集中。

第1步:编写基础 INNER JOIN 语句

我们的目标是获取 runoob_tbl 表中所有 runoob_author 字段在 tcount_tbl 表中对应的 runoob_count 值。

mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count 
    FROM runoob_tbl a 
    INNER JOIN tcount_tbl b 
    ON a.runoob_author = b.runoob_author;

参数说明:

  • ab 分别是 runoob_tbltcount_tbl 的表别名,用于简化查询语句。
  • ON a.runoob_author = b.runoob_author 指定了连接条件,即两个表通过作者名称进行匹配。

执行结果:

+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鸟教程    | 10             |
| 2           | 菜鸟教程    | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
+-------------+-----------------+----------------+
4 rows in set (0.00 sec)

注意:由于 runoob_tbl 中作者为 FK 的记录在 tcount_tbl 中没有匹配,因此该记录未出现在结果中。

第2步:使用 WHERE 子句进行过滤

INNER JOIN 的基础上,可以进一步使用 WHERE 子句对结果进行筛选。例如,只查询特定日期之后的订单:

SELECT orders.order_id, customers.customer_name
FROM orders
INNER JOIN customers ON orders.customer_id = customers.customer_id
WHERE orders.order_date >= '2023-01-01';

此语句先进行表连接,再根据 order_date 过滤结果,确保只返回符合条件的数据。

第二步:使用 LEFT JOIN 保留左表所有记录

LEFT JOIN(左连接)会返回左表的所有行,即使右表中没有匹配的记录。当右表没有匹配时,相关列将显示为 NULL

第3步:编写基础 LEFT JOIN 语句

runoob_tbl 为左表,tcount_tbl 为右表,获取所有教程及其对应的登录次数(如果存在):

mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count 
    FROM runoob_tbl a 
    LEFT JOIN tcount_tbl b 
    ON a.runoob_author = b.runoob_author;

执行结果:

+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鸟教程    | 10             |
| 2           | 菜鸟教程    | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
| 5           | FK              | NULL           |
+-------------+-----------------+----------------+
5 rows in set (0.01 sec)

可以看到,即使 FK 作者在 tcount_tbl 中不存在,其记录依然被保留,只是 runoob_count 显示为 NULL

第4步:LEFT JOIN 结合 WHERE 过滤的注意事项

如果在 LEFT JOIN 后直接使用 WHERE 过滤右表字段,可能会意外过滤掉左表中无匹配的记录。例如:

SELECT customers.customer_id, customers.customer_name, orders.order_id
FROM customers
LEFT JOIN orders ON customers.customer_id = orders.customer_id
WHERE orders.order_date >= '2023-01-01' OR orders.order_id IS NULL;

必须显式添加 OR orders.order_id IS NULL,才能确保左表中无匹配订单的客户也被保留。

第三步:使用 RIGHT JOIN 保留右表所有记录

RIGHT JOIN(右连接)与 LEFT JOIN 相反,它返回右表的所有行,即使左表中没有匹配的记录。在实际开发中,RIGHT JOIN 并不常用,因为可以通过交换表顺序并使用 LEFT JOIN 实现相同效果。

第5步:编写基础 RIGHT JOIN 语句

runoob_tbl 为左表,tcount_tbl 为右表,获取所有作者及其登录次数(如果存在):

mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count 
    FROM runoob_tbl a 
    RIGHT JOIN tcount_tbl b 
    ON a.runoob_author = b.runoob_author;

执行结果:

+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鸟教程    | 10             |
| 2           | 菜鸟教程    | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
| NULL        | NULL            | 22             |
+-------------+-----------------+----------------+
5 rows in set (0.01 sec)

注意:由于 tcount_tbl 中作者为 Google 的记录在 runoob_tbl 中没有匹配,因此 runoob_idrunoob_author 显示为 NULL

第6步:将 RIGHT JOIN 转换为 LEFT JOIN

为了保持代码风格一致,建议将 RIGHT JOIN 转换为 LEFT JOIN,只需交换表顺序即可:

SELECT a.runoob_id, a.runoob_author, b.runoob_count 
FROM tcount_tbl b 
LEFT JOIN runoob_tbl a 
ON a.runoob_author = b.runoob_author;

此语句返回与 RIGHT JOIN 完全相同的结果,但更符合大多数开发团队的编码规范。

第四步:在 PHP 脚本中执行 JOIN 查询

在 PHP 应用中,可以使用 mysqli_query() 函数执行 SQL 语句。以下是一个完整的 PHP 示例,演示如何使用 INNER JOIN 获取数据并输出为 HTML 表格:

菜鸟教程 MySQL JOIN 测试

'; echo ''; while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC)) { echo " ". " ". " ". ""; } echo '
教程 ID作者登陆次数
{$row['runoob_id']}{$row['runoob_author']} {$row['runoob_count']}
'; mysqli_close($conn); ?>

执行说明:

  • mysqli_connect() 用于建立数据库连接。
  • mysqli_query() 执行 SQL 查询。
  • mysqli_fetch_array() 逐行获取结果集,并输出为 HTML 表格。

常见问题与调整建议

  • 问题:JOIN 查询结果比预期少。
    原因:使用了 INNER JOIN,而某些记录在另一个表中没有匹配项。
    解决:如需保留所有记录,改用 LEFT JOINRIGHT JOIN
  • 问题:LEFT JOIN 后 WHERE 过滤掉了左表无匹配的记录。
    原因:直接在 WHERE 中过滤右表字段,导致无匹配的记录被排除。
    解决:WHERE 条件中添加 OR 右表字段 IS NULL
  • 问题:RIGHT JOIN 使用频率低,代码可读性差。
    原因:RIGHT JOIN 不符合大多数开发团队的编码规范。
    解决:交换表顺序,改用 LEFT JOIN,保持代码风格一致。

总结

MySQL 的 JOIN 语句是多表查询的核心工具。掌握 INNER JOINLEFT JOINRIGHT JOIN 的区别与适用场景,能够帮助开发者高效地处理复杂的数据关联需求。在实际开发中,建议优先使用 INNER JOINLEFT JOIN,并通过表别名和连接条件优化查询性能。

以上就是 MySQL JOIN 多表查询实战:INNER、LEFT 与 RIGHT 连接的详细内容,更多关于 MySQL 数据库教程的资料请关注本站其它相关文章!

来源:https://www.runoob.com/mysql/mysql-join.html
上一篇MySQL NULL 值处理:查询、替换与排序实战指南 下一篇MySQL UNION 操作符:语法、UNION与UNION ALL区别及实战示例
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

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

同类最新

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

更多
Redis Hash 哈希散列:底层原理、存储结构与常用命令详解
数据库 · 2026-08-31

Redis Hash 哈希散列:底层原理、存储结构与常用命令详解

本文详解 Redis Hash 哈希散列的底层存储结构(ziplist 与 dict)、哈希冲突解决机制及常用命令操作。通过图解与实战示例,帮助开发者掌握 Hash 类型在对象存储场景中的高效应用与内存优化策略。

Redis Set 集合详解:底层原理、常用命令与实战示例
数据库 · 2026-08-31

Redis Set 集合详解:底层原理、常用命令与实战示例

本文系统讲解 Redis Set 集合的核心特性与底层存储机制,涵盖 intset 与哈希表的切换条件、结构体定义及内存优化策略。通过完整命令汇总与终端交互示例,帮助开发者掌握集合操作、交集 并集 差集计算及实际应用场景。

Redis连接命令详解:AUTH、PING、SELECT等命令使用指南
数据库 · 2026-08-31

Redis连接命令详解:AUTH、PING、SELECT等命令使用指南

本文详细解析Redis连接命令,包括AUTH、PING、SELECT、ECHO和QUIT等核心命令的语法、参数、返回值及常见错误处理。通过实操示例演示如何建立连接、验证密码、切换数据库及安全断开连接,帮助开发者快速掌握Redis客户端与服务端的交互机制。

Redis PubSub发布订阅模式详解:命令、流程与使用场景
数据库 · 2026-08-31

Redis PubSub发布订阅模式详解:命令、流程与使用场景

Redis PubSub(发布 订阅)是一种基于频道的消息多播机制,适用于实时通知与轻量级解耦场景。本文通过图解与终端交互示例,演示订阅、发布与接收的完整流程,汇总常用命令并说明模式匹配与状态查询方法,帮助开发者快速掌握其使用边界与注意事项。

Redis Stream消息队列:核心概念、命令与实战指南
数据库 · 2026-08-31

Redis Stream消息队列:核心概念、命令与实战指南

Redis 5 0引入的Stream数据类型提供了具备持久化与主从复制能力的消息队列功能。本文系统梳理Stream的核心架构、消息ID生成规则、消费组机制及ACK确认流程,并通过完整的CLI命令示例演示消息的发布、消费与状态管理,帮助开发者快速掌握Redis Stream的实战用法。