mysql根本不支持full join,执行即报error 1064;需用left join加not exists与union all拼接右表独有数据,并注意null处理、字段对齐及类型声明。

MySQL根本不支持FULL JOIN
直接说结论:如果你用的是MySQL,FULL JOIN语法会报错——ERROR 1054 (42S22): Unknown column '...' in 'field list'或更常见的ERROR 1064 (42000): You have an error in your SQL syntax。因为MySQL至今(8.0/8.4)仍不原生支持FULL JOIN,这不是你写错了,是它压根没这个功能。
用LEFT JOIN + RIGHT JOIN + UNION ALL模拟FULL JOIN
核心思路是把“左表全量 + 右表中左表没有匹配的行”和“右表全量 + 左表中右表没有匹配的行”拼起来,再去重重复的匹配行。实际写法要注意三点:
- 必须用
UNION ALL而非UNION,否则性能差且可能误删本该保留的重复行(比如两表都有相同空值组合) -
LEFT JOIN部分要加WHERE right_table.id IS NULL,RIGHT JOIN部分要加WHERE left_table.id IS NULL,否则会把已匹配的行重复计算两次 - 所有字段需显式列出并保持顺序一致,不能用
*,否则UNION会因列数或类型不匹配失败
示例(假设两表都有id和name):
SELECT l.id, l.name, r.value FROM left_table l LEFT JOIN right_table r ON l.id = r.id WHERE r.id IS NULL UNION ALL SELECT r.id, r.name, r.value FROM right_table r LEFT JOIN left_table l ON r.id = l.id WHERE l.id IS NULL UNION ALL SELECT l.id, l.name, r.value FROM left_table l INNER JOIN right_table r ON l.id = r.id;
PostgreSQL/SQL Server可以直接用FULL JOIN但要注意NULL处理
这些数据库支持标准语法,但真实场景里最容易出问题的是ON条件中的NULL参与比较——比如ON a.key = b.key时,若任一key为NULL,整行不会被匹配,最终出现在结果里但对应字段全为NULL。这不是bug,是SQL三值逻辑的必然结果。
- 如果业务上需要把
NULL当作可匹配值,得改写条件,例如ON (a.key = b.key) OR (a.key IS NULL AND b.key IS NULL) -
FULL JOIN结果集可能比两表行数之和还大——当左表某行匹配右表多行时,会产生笛卡尔积式膨胀 - 在WHERE中过滤
FULL JOIN结果时,务必区分WHERE col IS NOT NULL(过滤掉某侧无匹配的行)和WHERE col = 'x'(只保留匹配且值为x的行),后者会自动排除掉NULL填充的记录
用COALESCE统一主键字段避免后续判断混乱
做FULL JOIN后,左右表的关联字段(如id)在结果里各占一列,但实际业务常需要一个“合并后的唯一标识”。这时别手动写CASE WHEN,直接用COALESCE(l.id, r.id)——它返回第一个非NULL值,既简洁又符合语义。
- 注意:如果两表该字段都允许NULL,且某行恰好两边都是NULL,
COALESCE也会返回NULL,此时需额外补默认值,比如COALESCE(l.id, r.id, -1) - 别在JOIN条件里用
COALESCE替代等值判断,比如ON COALESCE(l.id, -1) = COALESCE(r.id, -1),这会导致索引失效且逻辑偏离原始意图
真正麻烦的不是写法本身,而是意识到FULL JOIN的结果天然稀疏——大量NULL意味着你后续每用一个字段都得主动考虑空值分支,漏判一处就可能让统计口径偏移。











