本节摘要:JOIN 把多张表按关联条件连成一张结果表。本节讲 INNER/LEFT/RIGHT/FULL 四种 JOIN 的区别和用法,以及 JOIN 的写法和性能注意。
阅读完本节,你应当能够:
数据分散在多张表里(第 2 章讲的关系模型),查"每个客户的订单金额"要把 Customers 和 Orders 连起来,这就是 JOIN。JOIN 按关联条件(通常是主外键)把两表的行配对。
SELECT Customers.FirstName, Orders.Amount FROM Customers JOIN Orders ON Customers.CustomerID = Orders.CustomerID;

四种 JOIN 的区别在于"保留哪边":
-- 所有客户及其订单(没订单的客户也显示,金额为 NULL) SELECT Customers.FirstName, Orders.Amount FROM Customers LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID;
JOIN 涉及多表,列名可能重名(如两表都有 CustomerID),用表别名前缀区分,并给表起短别名简化:
SELECT c.FirstName, o.Amount FROM Customers c JOIN Orders o ON c.CustomerID = o.CustomerID;
Customers c 给表起别名 c,后面用 c.CustomerID 引用。多表 JOIN 必用别名,否则写起来很长。
可以连续 JOIN 多张表:
SELECT c.FirstName, o.Amount, p.ProductName FROM Customers c JOIN Orders o ON c.CustomerID = o.CustomerID JOIN OrderItems oi ON o.OrderID = oi.OrderID JOIN Products p ON oi.ProductID = p.ProductID;
⚠️ 常见坑:JOIN 忘写 ON 条件,得到笛卡尔积——1000 行 × 1000 行 = 100 万行,查询爆炸。JOIN 必须有 ON 条件。
💡 关键直觉:JOIN 按 ON 条件配对两表行,INNER 取交集、LEFT 左全、RIGHT 右全、FULL 全集。关联列建索引,多表 JOIN 用别名简化。
表 别名 起短名,用 别名.列 引用。下一节讲子查询——把查询嵌进查询。
Q1:JOIN 忘记写 ON 条件会发生什么?
变成笛卡尔积:左表每一行和右表每一行都组合。两表各 1000 行就出 100 万行,既慢又没意义。这是新手最容易犯的错,务必写完 JOIN 检查 ON 是否齐全。
Q2:INNER JOIN 和 LEFT JOIN 结果行数怎么判断?
INNER 只返回两边匹配上的行;LEFT 返回左表所有行,右表没匹配上的用 NULL 补齐。判断行数时记住:LEFT JOIN 结果行数大于等于左表行数(右表有重复匹配时更多)。写 JOIN 前先想清楚"要保留哪边的所有行"。
Q3:三张表以上怎么 JOIN?
逐个连:A JOIN B ON ... JOIN C ON ...。注意连接顺序和条件归属。三表 JOIN 时,建议每步都写清楚 ON,并只关联必要的表,避免无谓的行数膨胀。
Q4:JOIN 时怎么用 WHERE 过滤?
可以在 JOIN 之后加 WHERE 过滤结果。但要注意:LEFT JOIN 后对右表列加 WHERE 条件,会把"没匹配上的 NULL 行"过滤掉,效果变成 INNER JOIN。如果想保留左表全部,过滤条件要放在 ON 里或先对右表做子查询过滤。这是 JOIN 进阶最重要的坑。
Q5:关联列必须有索引吗?
是。JOIN 本质是"用左表每行去右表找匹配",右表关联列有索引才能高效查找,否则全表扫描。外键列一般自动建索引或建议建索引。慢 JOIN 的首要排查项就是关联列索引。
Q6:FULL JOIN 为什么用得少?
因为两边都不匹配的行都保留,语义"全量",实际业务中"既要左表全部又要右表全部"的场景少。且 MySQL 不支持 FULL JOIN(需用 UNION 模拟),所以日常以 INNER、LEFT 为主。
连接是理解和练习并重的主题,建议用最笨也最有效的方式:手动画表。
准备两个小表,比如客户表和订单表,各插入三五条数据,其中让部分客户没有订单、部分订单没有对应客户。
第一步,把两表内容画在纸上,左边一列客户,右边一列订单。
第二步,手动模拟内连接:把两边都能匹配上的行配成对,数一数结果有几行,记住内连接"只保留两边都有"。
第三步,手动模拟左连接:左边所有行都保留,右边配不上的补上"空"标记,再数一次行数,记住左连接"左边全保留"。
第四步,把同样的模拟做到右连接和全连接上,对比四种结果的行数和"谁被保留"。
第五步,再把模拟结果和数据库实际查询结果对比,确认你的理解无误。
这五步做完,四种连接的差别就不是背出来的,而是你自己推演出来的。连接是面试必考、工作常用的主题,这份亲手推演的体验,比任何口诀都可靠。
连接的本质是按条件给两边的行配对。内连接只留配上的,左连接左全留,右连接右全留,全连接全留。忘写条件会变成笛卡尔积,关联列要有索引才高效。