本文最后更新于46 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
RIGHT JOIN 详解
RIGHT JOIN(右连接) 是 SQL 中的一种连接方式,它会返回右表(RIGHT JOIN 后面的表)的所有记录,即使左表中没有匹配的记录。
基本语法
SELECT 列名
FROM 表A
RIGHT JOIN 表B ON 表A.列 = 表B.列;
- 表A:左表
- 表B:右表
- ON:指定连接条件
通俗理解
| 连接类型 | 返回结果 |
|---|---|
| INNER JOIN | 两表都匹配的记录 |
| LEFT JOIN | 左表全部 + 右表匹配的 |
| RIGHT JOIN | 右表全部 + 左表匹配的 |
| FULL JOIN | 两表全部(MySQL 不直接支持) |
RIGHT JOIN 相当于 LEFT JOIN 的反过来:
A RIGHT JOIN B等价于B LEFT JOIN A
实际例子
假设有两个表:
学生表 (students)
| id | name |
|---|---|
| 1 | 张三 |
| 2 | 李四 |
| 3 | 王五 |
成绩表 (scores)
| student_id | score |
|---|---|
| 1 | 90 |
| 2 | 85 |
| 4 | 88 |
RIGHT JOIN 示例:
SELECT students.name, scores.score
FROM students
RIGHT JOIN scores ON students.id = scores.student_id;
结果:
| name | score |
|——|——-|
| 张三 | 90 |
| 李四 | 85 |
| NULL | 88 |
解释:
- 右表
scores有 3 条记录,全部返回 - 学生表中 id=4 没有对应学生,所以 name 为 NULL
可视化对比
左表 (students) 右表 (scores)
+----+------+ +------------+-------+
| id | name | | student_id | score |
+----+------+ +------------+-------+
| 1 | 张三 | | 1 | 90 |
| 2 | 李四 | | 2 | 85 |
| 3 | 王五 | | 4 | 88 |
+----+------+ +------------+-------+
RIGHT JOIN 结果:
+------+-------+
| name | score |
+------+-------+
| 张三 | 90 | ← 匹配到
| 李四 | 85 | ← 匹配到
| NULL | 88 | ← 右表有,左表无
+------+-------+
各连接对比
-- 1. INNER JOIN:只返回匹配的
SELECT students.name, scores.score
FROM students
INNER JOIN scores ON students.id = scores.student_id;
-- 结果:张三(90), 李四(85)
-- 2. LEFT JOIN:返回左表全部
SELECT students.name, scores.score
FROM students
LEFT JOIN scores ON students.id = scores.student_id;
-- 结果:张三(90), 李四(85), 王五(NULL)
-- 3. RIGHT JOIN:返回右表全部
SELECT students.name, scores.score
FROM students
RIGHT JOIN scores ON students.id = scores.student_id;
-- 结果:张三(90), 李四(85), NULL(88)
什么时候用 RIGHT JOIN?
实际上,RIGHT JOIN 使用较少,因为大多数情况下可以用 LEFT JOIN 替代:
-- 这两个是等价的
A RIGHT JOIN B
-- 等价于
B LEFT JOIN A
使用场景示例:
-- 场景:找出所有订单及其对应的客户(包括没有客户的订单)
SELECT customers.name, orders.order_date
FROM customers
RIGHT JOIN orders ON customers.id = orders.customer_id;
-- 等价写法(更常用)
SELECT customers.name, orders.order_date
FROM orders
LEFT JOIN customers ON customers.id = orders.customer_id;
回到你的原查询
SELECT *
FROM persons AS a
RIGHT JOIN persons AS b ON b.position = 3;
这个查询的意思是:
- 右表是 b(也就是 persons 表)
- 返回 b 的所有记录
- 连接条件是
b.position = 3(这不是两个表之间的连接条件,只是过滤) - 因为没有真正的连接条件,a 表的每条记录都会与 b 表的每条记录配对(笛卡尔积)
快速记忆
| 关键词 | 记忆方法 |
|---|---|
| LEFT JOIN | 左表为主,左表全部保留 |
| RIGHT JOIN | 右表为主,右表全部保留 |
| INNER JOIN | 只保留两表都有的 |