MySQL不支持FULL JOIN是因为官方直到8.0.32版本仍未实现该语法,执行会报语法错误;可用LEFT JOIN加RIGHT JOIN再UNION模拟,但需注意去重、字段对齐及NULL处理。

MySQL 为什么没有 FULL JOIN
因为 MySQL 官方直到 8.0.32 版本仍不支持 FULL JOIN 语法,执行会直接报错:ERROR 1064 (42000): You have an error in your SQL syntax。这不是你写错了,是引擎压根不认这个关键词。PostgreSQL、SQL Server 支持,但 MySQL 就是没加——别查文档确认了,真没有。
用 LEFT JOIN + RIGHT JOIN + UNION 模拟 FULL JOIN 的正确写法
核心思路是:取左表全集(LEFT JOIN)和右表全集(RIGHT JOIN),再用 UNION 合并;但要注意去重逻辑,否则交集部分会重复两次。
实操建议:
- 必须用
UNION(不是UNION ALL),否则交集行重复 -
LEFT JOIN部分要补上右表为NULL的记录,RIGHT JOIN部分要补上左表为NULL的记录 - 两部分的字段顺序、数量、类型必须严格一致,否则
UNION会失败或隐式转换出错 - 如果连接字段有
NULL值,ON条件可能失效,建议提前用COALESCE或IS NULL处理
示例(模拟 t1 FULL JOIN t2 ON t1.id = t2.t1_id):
SELECT t1.id, t1.name, t2.t1_id, t2.value FROM t1 LEFT JOIN t2 ON t1.id = t2.t1_id UNION SELECT t1.id, t1.name, t2.t1_id, t2.value FROM t1 RIGHT JOIN t2 ON t1.id = t2.t1_id WHERE t1.id IS NULL;
性能差在哪?哪些场景要特别小心
这种模拟方式本质是跑两次 JOIN 再合并,IO 和计算开销翻倍,尤其当任一表超过 10 万行时,响应明显变慢。
容易踩的坑:
- 没加
WHERE t1.id IS NULL在RIGHT JOIN分支 → 交集重复,结果行数爆炸 - 字段别名不统一,比如左边选
t1.name,右边写t2.title→UNION报错或列对齐错乱 - 在子查询里套这个结构又加了
ORDER BY或LIMIT→ MySQL 5.7 可能报错This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' - 连接条件含函数,如
ON LOWER(t1.email) = LOWER(t2.email)→ 索引失效,JOIN 变全表扫描
有没有更轻量的替代方案
如果你只是想“查出所有关联数据 + 补齐缺失侧”,且业务允许分两步,比模拟 FULL JOIN 更快:
- 先
SELECT ... FROM t1 LEFT JOIN t2 ...得到左主+右匹配 - 再
SELECT ... FROM t2 WHERE t2.t1_id NOT IN (SELECT id FROM t1)补右独有(注意NOT IN对NULL敏感,建议改用NOT EXISTS) - 用应用层合并(比如 Python pandas.concat 或 Node.js 数组合并),避免 SQL 层复杂度
真正难处理的是需要基于完整结果再聚合(如 COUNT(*)、SUM()),这时还是得硬上 UNION 模拟,但务必在连接字段加索引,且预估数据量——万一行数超百万,就得考虑迁移到支持原生 FULL JOIN 的数据库,或者改用物化视图预计算。










