MySQL: MySQL连接查询JOIN完全指南

最后更新:2026-08-26

JOIN 是关系型数据库的核心能力——关联多张表才能发挥真正的威力。

本课系统讲解所有 JOIN 类型及实战应用。

1. 你将学到


2. 多表查询的真实故事

(1) 痛点:数据分散在多张表

订单数据在 orders 表,客户名在 customers 表。

想查"每个订单对应的客户名"——需要关联查询。

(2) JOIN 的解法

SQL
SELECT 
    o.id AS order_id,
    c.name AS customer_name,
    o.amount
FROM orders o
INNER JOIN customers c ON o.customer_id = c.id;

3. JOIN 类型总览

100%
graph LR
    A[JOIN 类型] --> B[INNER JOIN]
    A --> C[LEFT JOIN]
    A --> D[RIGHT JOIN]
    A --> E[CROSS JOIN]
    B --> F[只返回匹配行]
    C --> G[左表全返+右表匹配]
    D --> H[右表全返+左表匹配]
    E --> I[笛卡尔积]
JOIN 类型 说明 返回行数
INNER JOIN 两表都匹配的行 交集
LEFT JOIN 左表全部 + 右表匹配 左表全量
RIGHT JOIN 右表全部 + 左表匹配 右表全量
CROSS JOIN 笛卡尔积 m × n

4. INNER JOIN 内连接

只返回两表都匹配的行。

▶ 示例:基本内连接

SQL
-- 查询订单及客户信息
SELECT 
    o.id AS order_id,
    c.name AS customer_name,
    o.amount,
    o.order_date
FROM orders o
INNER JOIN customers c ON o.customer_id = c.id;

-- 三表连接
SELECT 
    o.id,
    c.name,
    p.product_name,
    oi.quantity
FROM orders o
INNER JOIN customers c ON o.customer_id = c.id
INNER JOIN order_items oi ON o.id = oi.order_id
INNER JOIN products p ON oi.product_id = p.id;
▶ 试一试

5. LEFT JOIN 左外连接

返回左表所有行,右表无匹配时返回 NULL。

▶ 示例:左连接

SQL
-- 查询所有客户及其订单(包括没订单的客户)
SELECT 
    c.name,
    o.id AS order_id,
    o.amount
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id;
▶ 试一试

输出:

TEXT 📖 仅展示
+----------+----------+--------+
| name     | order_id | amount |
+----------+----------+--------+
| Alice    |        1 | 100.00 |
| Alice    |        2 | 200.00 |
| Bob      |        3 | 150.00 |
| Charlie  |     NULL |   NULL |  -- 没有订单
+----------+----------+--------+

▶ 示例:找出没有订单的客户

SQL
SELECT c.*
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
WHERE o.id IS NULL;
▶ 试一试

6. RIGHT JOIN 右外连接

返回右表所有行,左表无匹配时返回 NULL。

▶ 示例:右连接

SQL
-- 查询所有订单及其客户(包括无效订单)
SELECT 
    c.name,
    o.id AS order_id,
    o.amount
FROM customers c
RIGHT JOIN orders o ON c.id = o.customer_id;
▶ 试一试
💡 提示: RIGHT JOIN 较少使用,通常可以用 LEFT JOIN 替代(调换表顺序)。


7. CROSS JOIN 交叉连接

返回笛卡尔积(每行 × 每行)。

▶ 示例:交叉连接

SQL
-- 生成颜色×尺寸组合
SELECT c.color, s.size
FROM colors c
CROSS JOIN sizes s;
▶ 试一试

输出(3 色 × 3 尺寸 = 9 行):

TEXT 📖 仅展示
+-------+------+
| color | size |
+-------+------+
| Red   | S    |
| Red   | M    |
| Red   | L    |
| Blue  | S    |
| Blue  | M    |
| Blue  | L    |
| Green | S    |
| Green | M    |
| Green | L    |
+-------+------+

8. USING 语法

当连接字段名相同时,可用 USING 简化。

▶ 示例:USING 简化

SQL
-- ON 写法
SELECT * FROM orders o
INNER JOIN customers c ON o.customer_id = c.id;

-- USING 简化(字段名必须相同)
SELECT * FROM orders
INNER JOIN customers USING (customer_id);
▶ 试一试

9. 自连接

表与自身关联。

▶ 示例:查找员工及其上级

SQL
-- 员工表有 manager_id 字段指向自己的 id
SELECT 
    e.name AS employee,
    m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;
▶ 试一试

输出:

TEXT 📖 仅展示
+----------+---------+
| employee | manager |
+----------+---------+
| Alice    | NULL    |  -- CEO,无上级
| Bob      | Alice   |
| Charlie  | Alice   |
| Dave     | Bob     |
+----------+---------+

10. JOIN 优化基础

优化策略 说明
连接字段加索引 ON o.customer_id = c.id 中的字段要有索引
小表驱动大表 小结果集的表放左边
避免 SELECT * 只查需要的字段
WHERE 提前过滤 减少参与 JOIN 的行数

❓ 常见问题

Q INNER JOIN 和 JOIN 有区别吗?
A 没有。JOIN 默认就是 INNER JOIN
Q LEFT JOIN 和 RIGHT JOIN 能互换吗?
A 可以。A LEFT JOIN B 等价于 B RIGHT JOIN A。推荐统一用 LEFT JOIN。
Q JOIN 会很慢吗?
A 取决于数据量和索引。连接字段有索引时,百万级表 JOIN 也能秒级返回。
Q 能 JOIN 多少张表?
A MySQL 理论无限制,但实际建议不超过 5-6 张。表太多考虑反范式设计。

📖 小节


📝 作业

  1. 基础题(难度⭐):用 INNER JOIN 查询订单及对应客户名称。

  2. 进阶题(难度⭐⭐):用 LEFT JOIN 找出从未下单的客户。

  3. 挑战题(难度⭐⭐⭐):用自连接查询员工及其上级,统计每个上级管理的下属数量。

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏