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

SQL RIGHT JOIN:保留右表的所有行

第 5.4 课 · 阅读时间:约 4 分钟

SQL RIGHT JOIN 返回右表的每一行以及左表中匹配的行;没有匹配时,左表的列为 NULL。在本课中,你将学习 RIGHT JOIN 的语法,了解它如何与 LEFT JOIN 互为镜像,以及为什么大多数开发者会把它改写为 LEFT JOIN。

RIGHT JOIN 是 LEFT JOIN 的镜像。区别只在于哪张表保留所有行:使用 LEFT JOIN 时是 FROM 之后的表,使用 RIGHT JOIN 时是 JOIN 之后的表。

SQL RIGHT JOIN:保留右表的所有行,没有匹配的行在左表的列中得到 NULL;结果与交换表位置后的 LEFT JOIN 相同

RIGHT JOIN 返回什么

  • 右表(RIGHT JOIN 之后的表)的每一行都会出现在结果中。
  • 有匹配的行会与匹配行组合,就像 INNER JOIN 一样。
  • 没有匹配的行在左表的所有列中得到 NULL。

RIGHT JOIN 和 RIGHT OUTER JOIN 是一样的。

基本语法

SELECT left_table.column1, right_table.column2
FROM left_table
RIGHT JOIN right_table ON left_table.key_column = right_table.key_column;

示例:所有地址及其员工

address 表存储客户、员工和门店的地址。要列出所有地址并显示其中哪些属于员工:

SELECT s.first_name, s.last_name, a.address, a.district
FROM staff AS s
RIGHT JOIN address AS a ON s.address_id = a.address_id
ORDER BY s.staff_id IS NULL, a.address
LIMIT 10;

结果:全部 603 个地址;两位员工的地址及其姓名排在最前面,其余地址的 first_name 和 last_name 为 NULL。


把 RIGHT JOIN 写成 LEFT JOIN

任何 RIGHT JOIN 都可以通过交换两张表改写为 LEFT JOIN。下面两个查询返回相同的行:

-- RIGHT JOIN:保留所有地址
SELECT s.first_name, s.last_name, a.address
FROM staff AS s
RIGHT JOIN address AS a ON s.address_id = a.address_id;
-- 交换表位置的 LEFT JOIN:结果相同
SELECT s.first_name, s.last_name, a.address
FROM address AS a
LEFT JOIN staff AS s ON s.address_id = a.address_id;

结果:两个查询都返回 603 行。

大多数开发者只使用 LEFT JOIN。这样查询读起来更自然:主表排在 FROM 之后的第一位,后续的每个连接只是为它补充信息。在一个查询中混用 LEFT 和 RIGHT,会让人难以看出哪些行一定会保留。


RIGHT JOIN 何时有用

  • 阅读已有代码。你会在他人编写的查询和工具生成的查询中遇到 RIGHT JOIN。
  • 在长查询末尾添加一张表。有时追加一个 RIGHT JOIN 比重新排列一长串连接更简单。即便如此,用 LEFT JOIN 改写后的查询通常更清晰。

SQLite 直到 3.39 版(2022 年)才支持 RIGHT JOIN;在更早的版本中,请交换表的位置并使用 LEFT JOIN。


要点:

  • RIGHT JOIN 保留右表的每一行;没有匹配的行在左表的列中得到 NULL。
  • A RIGHT JOIN B 返回的行与 B LEFT JOIN A 相同。
  • 大多数查询使用 LEFT JOIN,并把主表放在 FROM 之后:这样更易读。
  • 避免在一个查询中混用 LEFT JOIN 和 RIGHT JOIN。

常见问题

LEFT JOIN 和 RIGHT JOIN 有什么区别?

LEFT JOIN 保留 FROM 之后那张表的所有行;RIGHT JOIN 保留 JOIN 之后那张表的所有行。交换两张表就能把其中一种变成另一种。

为什么开发者很少使用 RIGHT JOIN?

因为交换表位置后的 LEFT JOIN 结果相同,而且读起来更自然:主表排在前面,被连接的表为它补充细节。

RIGHT JOIN 和 RIGHT OUTER JOIN 一样吗?

一样。关键字 OUTER 可以省略。