🎯 本月只剩几天支持 SQLTest.online,帮助我们让 SQL 练习对每个人都免费。 今天捐赠 →
SQL 代码已复制到剪贴板

SQL JOIN:如何在关系数据库中组合表

第 5.1 课 · 阅读时间:约 8 分钟 · 练习题 ↓

SQL JOIN 根据相关列把两张或多张表的行组合在一起。在本课中,你将学习 JOIN 背后的核心概念、如何编写 ON 条件、为什么表别名很重要,以及如何一步步从 Sakila 数据库中查询相关数据。

在关系数据库中,信息以一组相互关联的表的形式存储。要从中提取有意义的数据,就需要知道如何把它们连接起来。SQL 中的 JOIN 操作正是为此而设计的:它可以根据相关列把两张或多张表的行组合起来。

本课为理解 JOIN 这一处理关系型数据的关键概念打下基础。

SQL JOIN 基础:customer 表的行通过 address_id 与 address 表的行匹配,以及 customer、address、city 的键链

什么是 SQL JOIN,它如何工作?

JOIN 是一种把不同表中的行组合成一个结果集的机制。连接依据一个条件进行,这个条件通常比较键列中的值。

设想有两张表:customer 和 payment。payment 表中有一列 customer_id,表示这笔付款是哪位客户支付的。JOIN 可以把这两张表的行“拼接”起来,这样每笔付款不仅能看到客户 ID,还能看到客户姓名。

工作原理:

  1. 指定要连接的两张表。
  2. 在 ON 子句中定义连接条件,例如 customer.customer_id = payment.customer_id。
  3. 数据库遍历各行,找到匹配的配对,并由它们组成新的组合行。

示意图:

  Table A (customer)      Table B (payment)
  +----+-------+            +----+----------+
  | id | name  |            | id | amount   |
  +----+-------+            +----+----------+
  | 1  | Ivan  | <-----\    | 1  | 100.00   |
  | 2  | Maria |       \--->| 1  | 50.00    |
  | 3  | Petr  |            | 3  | 200.00   |
  +----+-------+            +----+----------+

箭头表示 payment 表中的行如何根据匹配的 id 在 customer 表中找到对应的客户。

如何在实践中使用 JOIN:Sakila 示例

来看看在使用 Sakila 数据库的真实 SQL 查询中是什么样子。

  1. 获取客户及其付款列表: 这条查询连接 customer 表和 payment 表,在每笔付款旁边显示客户的名字和姓氏。

    SELECT
        c.first_name,
        c.last_name,
        p.amount,
        p.payment_date
    FROM
        customer AS c
    JOIN
        payment AS p ON c.customer_id = p.customer_id;
    
    • JOIN payment AS p 表示要连接 payment 表。
    • ON c.customer_id = p.customer_id 是定义行之间如何关联的条件。
    • c 和 p 是别名,能让查询更简短、更易读。
  2. 获取电影及其语言列表: 连接 film 表和 language 表,显示每部电影的片名及其语言。

    SELECT
        f.title,
        l.name AS language
    FROM
        film AS f
    JOIN
        language AS l ON f.language_id = l.language_id;
    

    这里的关系通过 language_id 键建立。


本课要点:

  • SQL JOIN 把两张或多张表的行组合成一个结果集。
  • ON 条件定义不同表的行如何关联,通常是匹配键列。
  • 表别名(customer AS c)能缩短查询,使其更易读。
  • JOIN 不会修改原始数据,它生成的是一个临时结果集。
  • 在后续课程中,我们将详细学习 INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL JOIN。

常见问题

JOIN 和 INNER JOIN 有什么区别?

在 SQL 中,单独写 JOIN 就是 INNER JOIN 的简写,两者的结果完全相同。为了清晰起见,通常更推荐显式写出 INNER JOIN,尤其是在同一条查询中混用不同类型的连接时。

如果 ON 条件没有匹配到任何行,会发生什么?

如果没有行满足 ON 条件,INNER JOIN 会返回空结果集。不会报错,查询只是返回零行。其他连接类型(LEFT JOIN 等)对未匹配的行有不同的处理方式。

一条查询中可以连接两张以上的表吗?

可以。你可以在一条查询中串联多个 JOIN 子句,每个子句都有自己的 ON 条件。数据库按从左到右的顺序处理它们,逐步构建结果集。


面试问题

你会如何向不懂技术的同事解释 JOIN?

JOIN 就像用一个共同的 ID 在两张电子表格之间查找相关信息。例如,一张表列出了带 ID 的客户,另一张表列出了带客户 ID 的付款,JOIN 能让你看到每笔付款对应的客户姓名,而不必在任何一张表中重复数据。

什么是 ON 子句,为什么必须要有它?

ON 子句指定连接两张表的行的条件。如果没有它(或者条件无效),数据库会生成笛卡尔积:第一张表的每一行都与第二张表的每一行配对,这样的结果很少有用,而且可能非常庞大。

为什么在 JOIN 查询中使用表别名?

表别名能让查询更简短、没有歧义。当两张表有同名的列(例如都有 id)时,别名让你可以写成 c.id 和 p.id,这样数据库和读者都能准确知道指的是哪一列。

尝试解决以下任务,以巩固您在本课中学到的内容。

  1. SQL 表连接类型
  2. 选择连接类型
  3. 选择表连接类型
  4. 排查部署后事实表行数下降问题