讲师中心 微信公众号
AI工具推荐 视频效率加速

怎样在SQL中使用FULL OUTER JOIN合并两表差异数据

陌强小哥_4711

陌强小哥_4711

发布时间:2026-10-21 09:00:38

|

724人浏览过

|

来源于php中文网

原创

MySQL不支持FULL OUTER JOIN,会报ERROR 1064;需用LEFT JOIN + RIGHT JOIN(加WHERE过滤交集)+ UNION ALL组合模拟,注意字段对齐、NULL显式声明及NOT IN中NULL陷阱。

怎样在sql中使用full outer join合并两表差异数据

MySQL不支持FULL OUTER JOIN,得用LEFT + RIGHT模拟

直接写 FULL OUTER JOIN 在 MySQL 里会报错 ERROR 1064——它压根没实现这个语法。PostgreSQL、SQL Server、Oracle 支持,但 MySQL 用户必须手动拼:先 LEFT JOIN 拿左表全量 + 右表匹配行,再 RIGHT JOIN 补右表独有行,最后用 UNION ALL 合并(注意不是 UNION,避免去重开销)。

常见错误是漏掉 WHERE t2.id IS NULL 条件,导致 RIGHT JOIN 部分重复左表已存在的行。

  • LEFT JOIN 部分:保留所有左表记录,右表无匹配则字段为 NULL
  • RIGHT JOIN 部分:只取右表有、左表无的记录(加 WHERE t1.id IS NULL)
  • 两部分字段顺序、数量、类型必须一致,否则 UNION ALL 失败

PostgreSQL中FULL OUTER JOIN的NULL判断要小心

FULL OUTER JOIN 后,左右表都可能产生 NULL 值,但它们的语义不同:左表 NULL 表示“右表有这行,左表没匹配”,右表 NULL 表示“左表有这行,右表没匹配”。实际查差异时,不能只看某一边是否为 NULL,得组合判断。

比如想查“仅在表A存在”的数据,条件得写成:t1.id IS NOT NULL AND t2.id IS NULL;反过来查“仅在表B存在”就是 t1.id IS NULL AND t2.id IS NOT NULL。

  • 别写成 t2.id IS NULL 单独判断——它会把两表都不匹配的脏数据也捞出来(虽然少见,但JOIN条件松散时可能发生)
  • 如果JOIN字段允许 NULL,IS NULL 判断会误判;建议用非空主键或添加 COALESCE(t1.id, -1) != COALESCE(t2.id, -1) 辅助校验

性能差?因为FULL OUTER JOIN无法用索引优化右表驱动部分

LEFT JOIN 能走左表主键 + 右表外键索引,但 FULL OUTER JOIN(或模拟写法中的 RIGHT JOIN 部分)往往触发右表全扫描——尤其当右表大、左表小时,WHERE t1.id IS NULL 条件无法利用左表索引反向过滤。

实测过一个 500 万行右表 + 10 万行左表的场景,模拟 FULL OUTER JOIN 耗时 8.2 秒,而改用子查询预筛右表再 JOIN 降到 1.3 秒。

  • 优先考虑是否真需要全量合并:有时用 UNION ALL 拼两个 SELECT(分别查各自独有数据)更稳
  • 给 JOIN 字段建联合索引,如 (id, updated_at),避免回表放大 I/O
  • PostgreSQL 可加 /*+ Leading(t2) */ 提示(需开启扩展),但效果依赖统计信息准确度

用UNION ALL模拟时,列别名和NULL占位必须显式声明

模拟写法里,LEFT 和 RIGHT 两部分 SELECT 的列数、类型、顺序必须严格一致,否则 UNION ALL 直接报错。很多人卡在右边部分少写一个 NULL AS col_name,或者类型不匹配(比如左边是 VARCHAR(50),右边写 NULL 默认成 TEXT)。

示例:合并用户表和订单表,按 user_id 关联,但订单表可能缺用户信息:

SELECT u.id, u.name, o.order_id, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
UNION ALL
SELECT NULL, NULL, o.order_id, o.amount
FROM orders o
WHERE o.user_id NOT IN (SELECT id FROM users WHERE id IS NOT NULL);
  • 右边 SELECT 的前两列必须用 NULL AS name 显式对齐,不能靠数据库推断
  • NOT IN 子查询里加 WHERE id IS NOT NULL,防止因 NULL 导致整个条件返回空结果集
  • 若字段含 JSON 或 ARRAY 类型,某些数据库不支持 NULL 直接占位,得写 NULL::json 强制转类型
实际用的时候,先确认数据库版本是否原生支持,再决定走原生语法还是模拟路径;模拟路径看似啰嗦,但在 MySQL 或旧版 PostgreSQL 上反而更可控——尤其是当其中一张表数据量小、另一张大,且你只关心“差异”而非“全量合并”时,拆成两个独立查询通常更清晰、更易调优。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

4403

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

911

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

1149

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

6341

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

3143

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

6300

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

8601

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1170

2024.04.29

Playwright 测试失败怎么办
Playwright 测试失败怎么办

Playwright测试失败专题汇集超时、定位器匹配、浏览器提前关闭、依赖与插件配置、文件上传、SSL及Docker启动等故障文章,并介绍通过截图、报告和Trace定位错误。

0

2026.10.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn