今天我们来详细探讨一下 MySQL 中的“全连接”概念。
这是一个非常重要的话题,因为 MySQL 的一个显著特点是:它不支持标准的 FULL OUTER JOIN(全外连接)语法。但这并不意味着无法实现全连接的效果,我们需要通过其他方式模拟。
一、 核心概念:什么是全连接 (FULL OUTER JOIN)?
全连接的目的是返回两个表中的所有记录。它会将匹配的行进行连接,同时也会返回两个表中没有匹配到的行。对于未能匹配的部分,结果集中会用 NULL 填充。
结果集包括:
二、 MySQL 如何实现全连接?
既然 MySQL 不支持 FULL OUTER JOIN,我们使用 LEFT JOIN、RIGHT JOIN 和 UNION 操作符来模拟它。
基本语法结构:
(SELECT ... FROM table1 LEFT JOIN table2 ON ...)
UNION
(SELECT ... FROM table1 RIGHT JOIN table2 ON ...);
为什么用 UNION 而不是 UNION ALL?
UNION 会自动去除重复的行。UNION ALL 会保留所有行,包括重复的。UNION 来去重。三、 实战示例
假设我们有两个简单的表:customers (客户) 和 orders (订单)。
customers 表:
|
customer_id |
name |
|
1 |
Alice |
|
2 |
Bob |
|
3 |
Charlie |
orders 表:
|
order_id |
amount |
customer_id |
|
101 |
50.00 |
1 |
|
102 |
75.50 |
2 |
|
103 |
22.80 |
99 |
我们的目标是得到一个全连接的结果,显示所有客户和所有订单的关联情况。
步骤 1: 执行左连接 (LEFT JOIN) 获取所有客户及其订单(包括没有订单的客户)。
SELECT
c.customer_id,
c.name,
o.order_id,
o.amount
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id;
结果:
|
customer_id |
name |
order_id |
amount |
|
1 |
Alice |
101 |
50.00 |
|
2 |
Bob |
102 |
75.50 |
|
3 |
Charlie |
NULL |
NULL |
步骤 2: 执行右连接 (RIGHT JOIN) 获取所有订单及其客户(包括没有对应客户的“孤儿”订单)。
SELECT
c.customer_id,
c.name,
o.order_id,
o.amount
FROM customers c
RIGHT JOIN orders o ON c.customer_id = o.customer_id;
结果:
|
customer_id |
name |
order_id |
amount |
|
1 |
Alice |
101 |
50.00 |
|
2 |
Bob |
102 |
75.50 |
|
NULL |
NULL |
103 |
22.80 |
步骤 3: 使用 UNION 合并结果 将左连接和右连接的结果合并,并通过 UNION 去除中间重复的内连接部分(Alice 和 Bob 的记录)。
(
-- 左连接:获取所有客户+他们的订单(客户为主)
SELECT
c.customer_id,
c.name,
o.order_id,
o.amount
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
)
UNION
(
-- 右连接:获取所有订单+他们的客户(订单为主)
SELECT
c.customer_id,
c.name,
o.order_id,
o.amount
FROM customers c
RIGHT JOIN orders o ON c.customer_id = o.customer_id
);
最终全连接结果:
|
customer_id |
name |
order_id |
amount |
|
1 |
Alice |
101 |
50.00 |
|
2 |
Bob |
102 |
75.50 |
|
3 |
Charlie |
NULL |
NULL |
|
NULL |
NULL |
103 |
22.80 |
这个结果完美地展示了全连接的效果:匹配的行 + 仅左表存在的行 + 仅右表存在的行。
四、 注意事项和最佳实践
ON 子句)上的字段已建立索引。UNION 的两部分查询中,SELECT 的字段数量和数据类型必须严格一致。通常建议明确指定字段名而不是使用 SELECT *。UNION 查询作为一个子查询,然后在外部进行 WHERE 筛选。
SELECT * FROM (
(SELECT ... LEFT JOIN ...)
UNION
(SELECT ... RIGHT JOIN ...)
) AS full_result
WHERE full_result.amount > 100;
UNION 后的计算字段或整个派生表起一个别名,可以让外部查询更容易引用。总结
|
特性 |
MySQL 中的实现方式 |
|
全连接 (FULL OUTER JOIN) |
不支持原生语法 |
|
模拟全连接 |
使用 |
|
关键点 |
使用 |
虽然需要多写一些代码,但通过 UNION 来组合左连接和右连接,是 MySQL 中实现全连接功能的标准且有效的方法。
另外搭配便捷的MYSQL备份工具,可定时备份、异地备份,MYSQL导出导入。可本地连接LINUX里的MYSQL,简单便捷。可以大大地提高工作效率喔。
编辑