INNER JOIN 如何匹配行
掌握行配对的思维模型,轻松应对各种连接问题
INNER JOIN 如何匹配行 是 CoddyKit 上的免费 Coding Interview Prep 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Coding Interview Prep 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Coding Interview Prep 课程共包含 4 节课。
面试官首先会问的连接
当面试官说“连接这两张表”时,他们几乎总是指 INNER JOIN。它是默认的连接类型,也是最能体现您是否真正理解行如何配对的连接。
整个主题可以归结为一句话:INNER JOIN 会考虑两张表中所有可能的行对,并且只保留满足 ON 条件的行对。没有匹配项时,该行会直接从结果中消失。
牢记这个思维模型,所有更复杂的连接问题都会变得容易。
用于分析的两张表
在本课中,我们会一直使用两张小表。customers 保存下单的客户,orders 记录每一笔订单以及它所属的客户。
customers(id, name)orders(id, customer_id, amount)
两张表通过 orders.customer_id = customers.id 关联。这个等式就是整个结果所依赖的连接谓词。
customers
id | name
1 | Ada
2 | Bob
3 | Cleo -- no orders yet
orders
id | customer_id | amount
10 | 1 | 50
11 | 1 | 20
12 | 2 | 99基本的 INNER JOIN 查询
这是面试官希望看到的典型查询。请注意三个部分:两张表、用于配对行的 JOIN ... ON,以及要投影的列。
关键字 INNER 在所有主流数据库中都是可选的。直接写 JOIN 就表示 INNER JOIN,但明确写出 INNER 可以表明意图,并避免代码审查中的歧义。
SELECT c.name, o.amount
FROM customers AS c
INNER JOIN orders AS o
ON o.customer_id = c.id;结果是什么样的
在我们的示例数据上运行该查询,会得到三行。Ada 有两笔订单,因此会出现两次。Bob 出现一次。
Cleo 消失了。她没有匹配的订单,因此 INNER JOIN 会将她完全从结果中剔除。在连接面试中,明确说出不匹配的行会消失,是最重要的一点。
name | amount
Ada | 50
Ada | 20
Bob | 99行配对的思维模型
可以想象数据库先形成笛卡尔积:每个客户与每笔订单进行配对。3 个客户和 3 笔订单会产生 9 个候选行对。
然后它应用 ON 谓词,只保留谓词为真的行对。在 9 个候选行对中,只有 3 个满足 o.customer_id = c.id。
在考虑性能时,您不需要按照这种方式思考,但这是回答所有“会返回多少行?”问题的准确模型。
逐一查看候选行对
让我们追踪一下。每个行对后面的注释都会说明谓词是否为真。
只有三个 TRUE 行会留在结果中。所有包含 Cleo(id 3)的行对都会失败,因此她不会贡献任何结果。
-- customer.id vs order.customer_id
(Ada=1, ord10 cust=1) -> TRUE keep
(Ada=1, ord11 cust=1) -> TRUE keep
(Ada=1, ord12 cust=2) -> FALSE
(Bob=2, ord10 cust=1) -> FALSE
(Bob=2, ord12 cust=2) -> TRUE keep
(Cleo=3, anything) -> FALSE (no order matches 3)INNER JOIN 与表顺序无关
一个常见考点是:把哪张表放在前面重要吗?对于 INNER JOIN,不重要。由于 ON 条件具有对称性,这两个查询会返回完全相同的行。
无论您如何书写,优化器都可以自由选择先读取哪张表。(对于稍后会讲到的 LEFT/RIGHT 连接,情况并非如此。)
-- These return the same rows
SELECT c.name, o.amount
FROM customers c JOIN orders o ON o.customer_id = c.id;
SELECT c.name, o.amount
FROM orders o JOIN customers c ON c.id = o.customer_id;表别名是必需的
面试官希望看到简短、清晰的别名。请比较一下冗长的全限定写法和简洁的别名写法。
当两张表中都存在同名列时,别名也会变得必不可少。如果在这里直接选择 id,就会产生列名歧义错误,因此必须写成 c.id 或 o.id。
-- verbose
SELECT customers.name, orders.amount
FROM customers JOIN orders
ON orders.customer_id = customers.id;
-- aliased, preferred
SELECT c.name, o.amount
FROM customers c JOIN orders o
ON o.customer_id = c.id;基于多个列进行连接
ON 谓词并不局限于单个等式。当一个关系由复合键定义时,您需要使用 AND 将这些条件组合起来。
这里的价格按产品和地区分别适用,因此匹配时必须让两个列都对应起来。面试官会用这一点检查您是否只是记住了单列连接。
SELECT s.units, p.unit_price
FROM sales s
INNER JOIN price_list p
ON p.product_id = s.product_id
AND p.region = s.region;也存在非等值连接
ON 条件可以是任意布尔表达式,而不仅仅是 =。非等值连接使用范围或不等式。一个经典例子是根据分数将其归入某个等级区间。
每个分数都会匹配其所在范围对应的等级区间。提到连接并不局限于等值匹配,是快速体现资深程度的一种方式。
SELECT s.student, g.grade
FROM scores s
INNER JOIN grades g
ON s.points >= g.min_points
AND s.points <= g.max_points;显式 JOIN 与逗号连接
在遗留代码和一些面试题中,您仍然会遇到旧式的逗号连接语法。对于 INNER JOIN,下面两个查询是等价的。
请优先使用显式的 JOIN ... ON 形式。逗号语法很容易因为漏写 WHERE 而误写成意外的笛卡尔积,而这正是面试官希望发现的错误。
-- old implicit join
SELECT c.name, o.amount
FROM customers c, orders o
WHERE o.customer_id = c.id;
-- modern explicit join (preferred)
SELECT c.name, o.amount
FROM customers c
JOIN orders o ON o.customer_id = c.id;快速检查
测试 INNER JOIN 匹配这一核心概念。
回顾:INNER JOIN 如何进行匹配
面试中需要重复强调的要点:
- INNER JOIN 只保留匹配的行对;两侧未匹配的行都会消失。
- 思维模型:先形成所有候选行对,再保留 ON 谓词为真的行对。
- 它与顺序无关,而且
INNER关键字可以省略。 - ON 可以使用复合键、范围和不等式,而不仅仅是单个
=。 - 使用显式的
JOIN ... ON和清晰的别名,可以避免列名歧义和意外笛卡尔积错误。
常见问题解答
「INNER JOIN 如何匹配行」课时是免费的吗?
是的 — 「INNER JOIN 如何匹配行」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Coding Interview Prep 课程的其余内容,请升级到 CoddyKit PRO。 Coding Interview Prep 课程共包含 4 节课。
「INNER JOIN 如何匹配行」这节课中我会学到什么?
掌握行配对的思维模型,轻松应对各种连接问题 你通过在浏览器中直接运行的动手代码来练习 Coding Interview Prep,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Coding Interview Prep 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Coding Interview Prep 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「INNER JOIN 如何匹配行」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Coding Interview Prep 课中编写并运行代码吗?
能。每节 Coding Interview Prep 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- INNER JOIN 如何匹配行
- 连接中的 ON 与 WHERE
- 连接扩张与行数增加
- 连接三个或更多表