0

0

SQL的FULLOUTERJOIN是什么?全外连接的实现方法

看不見的法師

看不見的法師

发布时间:2025-09-06 13:21:03

|

754人浏览过

|

来源于php中文网

原创

FULL OUTER JOIN返回两表所有行,包含匹配及不匹配的记录,不匹配部分以NULL填充。它兼具LEFT JOIN和RIGHT JOIN的结果,适用于数据比对、审计、发现缺失或独有数据。当数据库不支持时,可用LEFT JOIN与RIGHT JOIN加WHERE条件筛选NULL后UNION ALL实现。

sql的fullouterjoin是什么?全外连接的实现方法

SQL的

FULL OUTER JOIN
(全外连接)是一种连接类型,它会返回两个表中所有匹配的行,同时也会包含那些在一个表中存在但在另一个表中没有匹配的行。对于没有匹配的行,来自另一张表的列会以
NULL
值填充。简单来说,它就是把左连接和右连接的结果合并起来,确保没有任何一个表的数据被遗漏。

FULL OUTER JOIN
的核心思想,我觉得用“兼顾并包”来形容最恰当不过了。它不像
INNER JOIN
那样只关注两边都有的“交集”,也不像
LEFT JOIN
RIGHT JOIN
那样偏袒某一方。它就像一个数据界的“大熔炉”,把所有能找到的关联都展示出来,同时对于那些“孤儿”数据(即只存在于一个表而另一个表没有对应项的数据),也一样会把它们拎出来,只是没有对应的那部分会用
NULL
来补位。

在实际操作中,如果你有两张表,比如一张是“客户信息表”,另一张是“订单记录表”,你可能想知道所有客户的信息,以及他们下过的订单;同时,你也想看看那些下了订单但可能因为某种原因(比如数据录入错误)在客户信息表里找不到对应客户的订单。反过来,你可能还想知道那些有客户信息但从未下过订单的“潜在客户”。这种情况下,

FULL OUTER JOIN
就能一次性满足你的所有需求。

它的语法结构通常是这样的:

SELECT
    列名1, 列名2, ...
FROM
    表A
FULL OUTER JOIN
    表B
ON
    表A.匹配列 = 表B.匹配列;

举个例子,假设我们有两张简单的表:

Employees
表: | EmployeeID | Name | |------------|--------| | 1 | Alice | | 2 | Bob | | 3 | Charlie|

Projects
表: | ProjectID | ProjectName | EmployeeID | |-----------|-------------|------------| | 101 | Alpha | 1 | | 102 | Beta | 2 | | 103 | Gamma | 4 |

如果我们执行一个

FULL OUTER JOIN

SELECT
    E.EmployeeID, E.Name, P.ProjectID, P.ProjectName
FROM
    Employees E
FULL OUTER JOIN
    Projects P
ON
    E.EmployeeID = P.EmployeeID;

结果会是这样:

EmployeeID Name ProjectID ProjectName
1 Alice 101 Alpha
2 Bob 102 Beta
3 Charlie NULL NULL
NULL NULL 103 Gamma

可以看到,Alice和Bob因为在两张表都有匹配,所以数据完整显示。Charlie在

Employees
表有,但在
Projects
表没有对应的项目,所以
ProjectID
ProjectName
NULL
。而ProjectID为103的Gamma项目,在
Projects
表有,但在
Employees
表没有对应的员工(EmployeeID=4不存在),所以
EmployeeID
Name
NULL
。这就是
FULL OUTER JOIN
的魅力所在,它真的做到了“一个都不能少”。

FULL OUTER JOIN
LEFT JOIN
RIGHT JOIN
有何不同?

这三者之间的区别,我觉得用一个简单的“包含关系”来理解会更直观。

FULL OUTER JOIN
可以说是
LEFT JOIN
RIGHT JOIN
的“超集”,它包含了这两者的所有信息,并且在处理方式上有着本质的不同。

  • LEFT JOIN
    (左外连接):以左表为基准。它会返回左表中的所有行,以及右表中与左表匹配的行。如果右表中没有匹配的行,那么右表的列会显示为
    NULL
    。想象一下,你只关心左边的数据,右边有就拿,没有也无所谓,左边的数据必须全在。

  • RIGHT JOIN
    (右外连接):与
    LEFT JOIN
    对称,以右表为基准。它会返回右表中的所有行,以及左表中与右表匹配的行。如果左表中没有匹配的行,那么左表的列会显示为
    NULL
    。这次你关心的是右边的数据,左边有就拿,没有也无所谓,右边的数据必须全在。

  • FULL OUTER JOIN
    (全外连接):它不偏袒任何一方。它会返回左表和右表中所有匹配的行。更重要的是,它还会返回那些只存在于左表但右表没有匹配的行,以及那些只存在于右表但左表没有匹配的行。对于没有匹配的行,对应的列会填充
    NULL
    。它追求的是“大团圆”,任何一方的独特数据都不会被舍弃。

简单来说:

  • LEFT JOIN
    = 左表全部 + 左右表交集。
  • RIGHT JOIN
    = 右表全部 + 左右表交集。
  • FULL OUTER JOIN
    = 左表独有 + 右表独有 + 左右表交集。

从实际应用的角度来看,当你明确知道你主要关心哪个表的数据,并且想把另一个表的数据“附加”上去时,

LEFT JOIN
RIGHT JOIN
是首选。但当你需要一个全面的视图,既要看到所有关联数据,又要找出两边各自“缺失”或“独有”的数据时,
FULL OUTER JOIN
就显得不可替代了。它能帮你发现数据不一致、数据录入遗漏等问题,是数据审计和数据清洗的好帮手。

微信二级防封域名
微信二级防封域名

防封域名方法千千种,我们只做最简单且有用的这一种。微信域名防封是指通过技术手段来实现预付措施,一切说自己完全可以防封的那都是不可能的,一切说什么免死域名不会死的那也是吹牛逼的。我们正在做的是让我们的推广域名寿命更长一点,成本更低一点,效果更好一点。本源码采用 ASP+ACCESS 搭建,由于要用到二级域名,所以需要使用独享云虚机或者云服务器,不支持虚拟主机使用,不支持本地测试。目前这是免费测试版,

下载

FULL OUTER JOIN
在实际业务场景中如何应用?

FULL OUTER JOIN
在实际业务中用途广泛,尤其是在需要全面比对、发现数据差异或进行数据整合的场景。我个人觉得,它最能体现价值的地方,就是它能帮助我们“发现异常”和“填补空白”。

一个非常典型的场景是数据同步或数据审计。假设你有一个老系统和一个新系统,它们都存储了客户信息,但数据可能存在不一致。你想找出:

  1. 在新老系统中都存在的客户(匹配)。
  2. 只存在于老系统但新系统没有的客户(可能需要迁移或已废弃)。
  3. 只存在于新系统但老系统没有的客户(新注册或新导入)。 这时候,对两个系统的客户表执行
    FULL OUTER JOIN
    ,通过检查
    NULL
    值,就能清晰地识别出这些不同类别的客户,为数据迁移、清洗或同步提供依据。

再比如,在销售和库存管理中。你可能有一张“产品销售记录表”和一张“当前库存表”。

  • FULL OUTER JOIN
    可以帮你找出:
    • 既有销售记录又有库存的产品(正常销售中)。
    • 有销售记录但目前库存为零的产品(可能已售罄,需补货)。
    • 有库存但从未有销售记录的产品(滞销品,可能需要促销)。 这种全面分析对于制定销售策略、优化库存结构非常有帮助。

另外,在用户行为分析中,比如你有一张“用户注册表”和一张“用户登录日志表”。通过

FULL OUTER JOIN
,你可以:

  • 找出既注册又登录的用户(活跃用户)。
  • 只注册但从未登录的用户(流失用户或注册未激活用户)。
  • 只存在登录日志但无注册信息的用户(这可能是一个数据异常,比如游客登录、匿名访问,或者数据源不一致)。 这种分析能帮助产品经理理解用户生命周期,优化用户引导流程。

它还能用于合并不同来源的数据集。比如,你有两个供应商提供的商品列表,它们可能有一些共同的商品,也有一些是各自独有的。你希望得到一个包含所有商品的综合列表,并且能清晰地看出哪些商品是哪个供应商提供的,哪些是两个供应商都有的。

FULL OUTER JOIN
就能很优雅地实现这一点。

总之,每当你的业务需求是“我需要看到所有相关数据,包括那些不完全匹配的部分,并且想知道哪些是独有的,哪些是共同的”,那么

FULL OUTER JOIN
就是你手里的那把“瑞士军刀”。

如果数据库不支持
FULL OUTER JOIN
,有哪些替代实现方法?

虽然大多数现代关系型数据库(如SQL Server, Oracle, PostgreSQL, MySQL 8.0+)都支持

FULL OUTER JOIN
,但如果你不幸遇到不支持它的数据库(比如某些旧版本的MySQL或者特定的嵌入式数据库),或者出于某些特定性能考虑,你仍然有办法实现同样的效果。最常见且最标准的方法是结合使用
LEFT JOIN
RIGHT JOIN
UNION ALL

这个替代方案的逻辑是这样的:

  1. 首先,我们用一个
    LEFT JOIN
    来获取所有左表的数据,以及它们在右表中的匹配项。如果右表没有匹配,右表列就为
    NULL
  2. 然后,我们需要获取那些只存在于右表,但在左表中没有匹配的行。这部分数据是
    LEFT JOIN
    无法捕捉到的。我们可以通过一个
    RIGHT JOIN
    来获取,但为了避免重复,我们需要筛选出那些在左表中没有匹配的行。

具体实现步骤和SQL代码如下:

假设我们有表

TableA
TableB
,通过
id
列进行连接。

-- 步骤1: 使用LEFT JOIN获取所有左表数据及其匹配项
-- 包含:TableA独有 + TableA与TableB交集
SELECT
    A.id AS A_id, A.value AS A_value,
    B.id AS B_id, B.value AS B_value
FROM
    TableA A
LEFT JOIN
    TableB B ON A.id = B.id

UNION ALL

-- 步骤2: 使用RIGHT JOIN获取所有右表数据,但只选择那些在左表中没有匹配的行
-- 包含:TableB独有
SELECT
    A.id AS A_id, A.value AS A_value,
    B.id AS B_id, B.value AS B_value
FROM
    TableA A
RIGHT JOIN
    TableB B ON A.id = B.id
WHERE
    A.id IS NULL; -- 关键:只选择右表有,但左表没有匹配的行

让我来详细解释一下

WHERE A.id IS NULL
这一句。在第二个
RIGHT JOIN
中,当
TableA
id
NULL
时,就意味着
TableB
的当前行在
TableA
中没有找到匹配项。这正是我们想要捕获的“只存在于右表”的数据。
UNION ALL
则负责将这两个结果集简单地堆叠在一起,因为它不会去除重复行,而我们的两个查询已经设计成互斥的(第一个查询包含交集和左独有,第二个查询只包含右独有),所以不会产生重复。

这种方法虽然能达到

FULL OUTER JOIN
的效果,但它通常会涉及两次全表扫描或索引扫描(取决于优化器和索引情况),并且需要
UNION ALL
来合并结果,这可能会比原生支持
FULL OUTER JOIN
的数据库直接执行一次操作的性能稍差。在数据量非常大的情况下,这一点需要特别注意。不过,对于大多数中小型数据集,或者在没有原生支持的情况下,这绝对是一个可靠且实用的替代方案。在选择时,我通常会优先考虑原生支持的
FULL OUTER JOIN
,因为它语义更清晰,也更可能得到数据库优化器的最佳处理。但如果条件不允许,上述方法是我的首选备胎。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

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

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

727

2023.10.12

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

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

327

2023.10.27

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

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

350

2024.02.23

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

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

1242

2024.03.06

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

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

360

2024.03.06

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

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

820

2024.04.07

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

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

581

2024.04.29

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

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

423

2024.04.29

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Rust 教程
Rust 教程

共28课时 | 5万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 2.9万人学习

Go 教程
Go 教程

共32课时 | 4.3万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号