hive&sql-LEFT JOIN之后,数据量为啥比左表还要少

本文揭示了在SQL LEFT JOIN操作中,ON条件和WHERE条件的区别:ON用于建立连接并决定左表全保留,而WHERE在连接后过滤数据。理解这一原理有助于避免因误用WHERE导致的数据不一致。通过实例和MySQL演示,解释了为何WHERE可能导致结果数据量减少。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

重现

a表 LEFT JOIN B表,结果表的数据量正常应该是=a表或者>a表(数据翻倍)。但有种情况,结果表会比a表少。

select 

a.XX,

...,

b.XX 

from  a 

left join b 

on a.id=b.id

where a.data_date=20210323 and b.data_date=20210323

逻辑很简单,就是用两个表的data_date做关联,但是结果却比 a 表的数据少了。当把唯一一个 “where” 换成 “and” 后,结果便正确了。这个原因其实是过滤数据的对象不同。
下面用 MySQL 创建示例来进行说明,

准备数据:分别创建两个表 emp和dept:

create table emp(

id int not null AUTO_INCREMENT PRIMARY KEY comment '员工编号',

name varchar(10) not null default '' comment '姓名',

dept_id int not null default 0 comment '所在部门编号'

) comment '员⼯表';


create table dept(

dept_id int not null AUTO_INCREMENT PRIMARY KEY comment '部门编号',

dept_name varchar(10) not null default '' comment '部门名称'

) comment '部门表';


insert into emp values (1,'张三',2),(2,'李四',2),(3,'王五',3),(4,'赵六',0),(5,'旺财',0);

insert into dept values (1,'财务部'),(2,'销售部'),(3,'研发部'),(4,'后勤部');

只用on,是我们想要的

select a.*,b.* from emp a left join dept b 
on a.dept_id =b.dept_id

在这里插入图片描述

如果加上 and a.dept_id = 2 ,结果也是我们想要的,如下:

select a.*,b.* from emp a left join dept b 
on a.dept_id = b.dept_id and a.dept_id = 2 

在这里插入图片描述
结果还是以左表为准,只是右边只有 dept_id = 2 的数据。
所以,LEFT JOIN时,无论ON的条件如何,左表不会被过滤,只会过滤右表。ON不仅是连接的条件,还是过滤条件,但只过滤右表(left join时)==》左表数据全部保留的情况下,需要保留哪些符合条件的右表数据

当把 and a.dept_id = 2 替换成 where a.dept_id = 2 ,结果就不正常了,如下:

select a.*,b.* from emp a left join dept b 
on a.dept_id = b.dept_id 
where a.dept_id = 2 

在这里插入图片描述
此时结果就比左表数据要少了。

summary

造成这种现象的原因是:
where是过滤条件,on是关联条件。注意!关联不是过滤,on条件只负责关联,关联上的就联接,匹不上的就置空。
数据库在通过两个表或者多个表返回数据时,都会生成一个中间的临时表,无论 on 条件的是否为真 ,都会返回左表的全部(以 left join 为例),如果右表无法匹配则补空。
而 where 后面的过滤条件是在生成临时表之后进行过滤的,只有 where 过滤条件为真的数据才会返回。

  • 通过 on 过滤的原理如下:
    在这里插入图片描述
  • 通过 where 过滤的原理如下::
    所以要么在子查询中对b表进行where,或者在on后面写
<think>嗯,用户问的是Hive SQL是否支持FULL JOIN。我需要先回忆一下Hive的文档知识。Hive是基于Hadoop的数据仓库工具,通常用于处理大规模数据SQL语法方面,Hive确实支持多种JOIN操作,比如INNER JOINLEFT JOIN、RIGHT JOIN,但FULL JOIN呢? 记得Hive在较新的版本中是支持FULL OUTER JOIN的,可能从某个版本开始添加了这个功能。不过,早期的Hive版本可能不支持或者存在一些限制。用户可能需要确认他们的Hive版本,因为如果版本太旧,可能无法使用FULL JOIN。 另外,HiveJOIN操作在处理大数据时需要注意性能问题。FULL JOIN会产生两个的并集,所有匹配和不匹配的行都会包含进来,这可能会导致数据量激增,尤其是在处理大时,需要谨慎使用,避免资源消耗过大。 用户可能是在处理需要合并两个所有数据的场景,比如合并用户的不同来源数据,或者需要统计两个中的所有记录,无论是否有匹配。这时候FULL JOIN就很有用。不过,用户可能也需要知道如何优化这样的查询,比如使用分区、分桶或者调整Hive的设置来优化执行计划。 还有,用户可能会混淆FULL JOIN和UNION操作,需要指出两者的区别。FULL JOIN是基于连接条件的合并,而UNION是合并两个查询的结果集,去除重复。不过,有时候用UNION ALL配合LEFT JOIN和RIGHT JOIN可以模拟FULL JOIN的效果,尤其是在旧版本不支持的情况下。 还需要提醒用户,使用FULL JOIN时,注意处理NULL值,因为当某一边的没有匹配时,对应的列会是NULL。在结果处理时,可能需要用COALESCE或者NVL函数来处理这些NULL值,确保后续分析的正确性。 另外,Hive在底层将JOIN转换为MapReduce任务或者Tez任务,不同的执行引擎可能会影响性能。FULL JOIN可能会生成复杂的任务,导致更多的shuffle和排序操作,用户可能需要监控作业的运行情况,调整资源分配。 总结一下,回答用户时需要确认Hive版本支持FULL JOIN,说明其用途和性能注意事项,并可能提供示例语法和使用建议。同时,如果用户使用的版本不支持,可以给出替代方案,比如使用UNION ALL和LEFT/RIGHT JOIN组合来实现类似效果。</think>是的,Hive SQL 支持 **FULL JOIN**(也称为 **FULL OUTER JOIN**)。它允许你合并两个的所有行,无论是否满足连接条件。不匹配的列会填充 `NULL` 值。 --- ### 语法示例: ```sql SELECT A.column1, B.column2 FROM table1 A FULL JOIN table2 B ON A.key = B.key; ``` --- ### 特点与注意事项: 1. **功能**: - 返回两个中所有匹配的行(类似 `INNER JOIN`)。 - 同时返回左表未匹配的行(右字段为 `NULL`)。 - 需要合并两个的全部数据(如数据补全、对比差异等)。 3. **性能问题**: - 大数据量时可能效率较低,需谨慎使用。 - 可通过分区、分桶或调整 Hive 参数(如 `mapreduce`/`tez` 引擎)优化。 4. **版本兼容性**: - 较新 Hive 版本(如 0.13+)支持良好,旧版本需确认兼容性。 --- ### 替代方案(如不支持 FULL JOIN): 若旧版本不支持,可通过 `UNION ALL` + `LEFT JOIN`/`RIGHT JOIN` 模拟: ```sql -- LEFT JOIN 部分 + RIGHT JOIN 未匹配部分 SELECT * FROM A LEFT JOIN B ON A.key = B.key UNION ALL SELECT * FROM A RIGHT JOIN B ON A.key = B.key WHERE A.key IS NULL; ``` --- ### 总结: Hive 的 `FULL JOIN` 适合需要全量合并数据的场景,但需注意性能和版本限制。使用时建议结合数据量和执行引擎调优。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值