为什么在SQL中执行FULL OUTER JOIN会出现大量NULL重复?

浅婷同学_3014

浅婷同学_3014

2026-10-27

836人浏览

原创

FULL OUTER JOIN结果中大量NULL并非重复,而是分别保留左表独有行(右字段为NULL)和右表独有行(左字段为NULL)所致;视觉上易误判,实为两组独立缺失。

为什么在sql中执行full outer join会出现大量null重复?

为什么FULL OUTER JOIN结果里一堆NULL还看起来像重复?

这不是“重复”,而是FULL OUTER JOIN的正常行为:它必须同时保留左表和右表的所有行,不匹配的部分用NULL填充。你看到的“大量NULL”,其实是两组独立的缺失——左表有、右表无;或右表有、左表无。它们在结果中物理上是不同行,但因大量字段为NULL,视觉上容易误判为“重复记录”。

FULL OUTER JOIN后行数暴增,但不是笛卡尔积导致的

和CROSS JOIN不同,FULL OUTER JOIN本身不会产生笛卡尔积式膨胀。但如果ON条件宽松(比如只靠status = 'active'而没绑定主键)、或某张表存在重复关联键(如t_user_tag里一个user_id对应5条标签),那匹配过程仍会触发一对多展开——此时左表1行 + 右表5行 → 结果出现5行,其中右表字段有值、左表其余字段为NULL的组合也会出现5次。

  • 检查方式:SELECT COUNT(*) FROM table_a FULL OUTER JOIN table_b ON ... 对比两张表原始行数之和;若远大于该和,说明ON条件没收敛
  • 典型陷阱:用非唯一列(如name)做JOIN键,同名用户/商品引发交叉匹配
  • MySQL不原生支持FULL OUTER JOIN,靠LEFT JOIN + RIGHT JOIN + UNION ALL模拟时,若没加WHERE筛出NULL侧,会把两边的NULL行重复包含

WHERE子句一加,FULL OUTER JOIN就“变味”了

写WHERE b.category IS NOT NULL会直接过滤掉所有右表不匹配的行,等价于退化成LEFT JOIN;同理WHERE a.id IS NULL会只留右表孤儿数据。真正想保留全集时,过滤逻辑必须挪到ON子句里,或用子查询预处理。

  • 错误写法:FULL OUTER JOIN b ON a.id = b.user_id WHERE b.status = 'valid' → 实际丢弃了所有右表不满足status的行,包括本该作为“右表孤儿”保留的记录
  • 正确写法:把条件放进ON:FULL OUTER JOIN b ON a.id = b.user_id AND b.status = 'valid'
  • 更安全的做法:先对右表用子查询GROUP BY或ROW_NUMBER()收敛粒度,再JOIN

用UNION ALL模拟FULL OUTER JOIN时,NULL字段对不齐

当数据库不支持原生FULL OUTER JOIN(如MySQL 5.7),常用LEFT JOIN + RIGHT JOIN + UNION ALL实现。但极易出错:两张子查询的列顺序、别名、数据类型稍有不一致,UNION ALL就会让NULL填错列,导致某列全是NULL、另一列数据错位,看起来像“重复又错乱”。

  • 必须显式写出所有列,不能用SELECT *:例如SELECT a.id, a.name, b.order_id, b.amount FROM ... 和 SELECT NULL AS id, NULL AS name, b.order_id, b.amount FROM ...
  • 注意字符串和数值型NULL的隐式转换风险,某些引擎会把NULL转成空字符串或0
  • UNION ALL不自动去重,若左右两边恰好有完全相同的行(极少见),会真实重复——这时才需要DISTINCT,但应放在最外层且明确知道代价

最容易被忽略的是:FULL OUTER JOIN的结果集,既不是左表的副本,也不是右表的副本,而是一个全新结构的数据集。一旦你把它当成主表继续JOIN第三张表,或者直接GROUP BY某个字段统计,那些看似“整齐”的NULL列会立刻干扰聚合逻辑——比如COUNT(b.order_id)漏算左表孤儿,AVG()跳过所有NULL却仍按总行数分母计算。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

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

相关专题

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

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

2023.10.12

4543

8

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

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

2023.10.27

951

4

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

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

2024.02.23

1189

5

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

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

2024.03.06

6521

10

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

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

2024.03.06

3283

4

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

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

2024.04.07

6480

11

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

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

2024.04.29

8881

6

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

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

2024.04.29

1210

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1052

5

热门下载

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

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习