在 MySQL 中,JOIN 操作用于将多个表中的数据关联查询。
以下是 INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL OUTER JOIN 的详细用法、区别及示例:
1. INNER JOIN(内连接)
-
作用:返回两个表中满足连接条件的记录。
-
特点:仅保留双方匹配的行,不匹配的行被丢弃。
-
语法:
SELECT columns FROM table1 INNER JOIN table2 ON table1.column = table2.column; -
示例:
-
表A(用户)和表B(订单)通过
user_id关联:SELECT * FROM users A INNER JOIN orders B ON A.user_id = B.user_id; -
结果:仅包含有订单的用户及其订单信息。
-
2. LEFT JOIN(左连接)
-
作用:返回左表(
table1)的所有记录,以及右表(table2)中匹配的记录。若右表无匹配,右侧字段为NULL。 -
特点:保留左表全部数据,右表无匹配则填充
NULL。 -
语法:
SELECT columns FROM table1 LEFT JOIN table2 ON table1.column = table2.column; -
示例:
SELECT A.name, B.order_id FROM users A LEFT JOIN orders B ON A.user_id = B.user_id;- 结果:所有用户(包括无订单的用户),无订单的用户的
order_id为NULL。
- 结果:所有用户(包括无订单的用户),无订单的用户的
3. RIGHT JOIN(右连接)
-
作用:返回右表(
table2)的所有记录,以及左表(table1)中匹配的记录。若左表无匹配,左侧字段为NULL。 -
特点:保留右表全部数据,左表无匹配则填充
NULL。 -
语法:
SELECT columns FROM table1 RIGHT JOIN table2 ON table1.column = table2.column; -
示例:
SELECT A.name, B.order_id FROM users A RIGHT JOIN orders B ON A.user_id = B.user_id;- 结果:所有订单(包括无用户的订单),无用户的订单的
name为NULL。
- 结果:所有订单(包括无用户的订单),无用户的订单的
4. FULL OUTER JOIN(全外连接)
-
作用:返回左右两表的全部记录。若某侧无匹配,对应字段为
NULL。 -
特点:MySQL 不直接支持
FULL OUTER JOIN,需通过LEFT JOIN和RIGHT JOIN的UNION实现。 -
语法(模拟):
SELECT columns FROM table1 LEFT JOIN table2 ON ... UNION SELECT columns FROM table1 RIGHT JOIN table2 ON ... WHERE table1.column IS NULL; -
示例:
SELECT A.name, B.order_id FROM users A LEFT JOIN orders B ON A.user_id = B.user_id UNION SELECT A.name, B.order_id FROM users A RIGHT JOIN orders B ON A.user_id = B.user_id WHERE A.user_id IS NULL;- 结果:所有用户和所有订单的组合,无匹配的部分为
NULL。
UNION 的核心作用
- 上下合并结果集:将多个
SELECT语句的结果合并为一个结果集。 - 去重:默认情况下,
UNION会去除重复的行(保留唯一行)。 - 保持列结构一致:要求所有
SELECT语句的列数相同,且对应列的数据类型兼容。
- 结果:所有用户和所有订单的组合,无匹配的部分为
关键区别总结
| JOIN 类型 | 保留左表数据 | 保留右表数据 | 匹配条件 | MySQL 直接支持 |
|---|---|---|---|---|
| INNER JOIN | 仅匹配的行 | 仅匹配的行 | 双方匹配 | ✔️ |
| LEFT JOIN | 所有行 | 仅匹配的行 | 左表为主 | ✔️ |
| RIGHT JOIN | 仅匹配的行 | 所有行 | 右表为主 | ✔️ |
| FULL OUTER JOIN | 所有行 | 所有行 | 无要求(全保留) | ❌(需模拟) |
示例数据与结果
假设:
-
表A(users) :
user_id name 1 Alice 2 Bob 3 Charlie -
表B(orders) :
order_id user_id amount 101 1 100 102 2 200 103 4 300 -
INNER JOIN 结果:
name order_id amount Alice 101 100 Bob 102 200 -
LEFT JOIN 结果:
name order_id amount Alice 101 100 Bob 102 200 Charlie NULL NULL -
RIGHT JOIN 结果:
name order_id amount Alice 101 100 Bob 102 200 NULL 103 300 -
FULL OUTER JOIN(模拟)结果:
name order_id amount Alice 101 100 Bob 102 200 Charlie NULL NULL NULL 103 300
使用建议
- 优先使用
INNER JOIN:当只需双方匹配的数据时。 - 使用
LEFT JOIN:需保留左表全部记录(如统计用户订单,包括无订单用户)。 - 慎用
RIGHT JOIN:通常可调换表顺序改用LEFT JOIN,代码更易读。 - 需要全外连接时:通过
UNION模拟,注意去重。
通过理解这些 JOIN 的区别,可以更灵活地根据业务需求选择合适的数据关联方式。