Hive中四种 join on筛选条件与where筛选条件的区别

本文深入探讨了SQL中四种Join类型(left join, right join, inner join, full join)的使用方法与区别,通过实例对比了on与where条件的不同效果,帮助读者理解如何正确应用Join操作以提高数据查询效率。

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

tableA的结构及数据:

id   name 	  grade	 dept 
1    lijie1   100.0   10
2    lijie2   90.0    20
3    lijie3   60.0    10
4    lijie4   80.0    10
5    lijie5   70.0    20

tableB的结构及数据:

id    name 
10    IT1
20    IT2

1、两张left join且同时查询分数大于80的数据

条件放在on上面

select a.id,a.name,a.grade,a.dept,b.id,b.name from tableA a left join tableB b on a.dept=b.id and a.grade>80;

on结果为:

a.id    a.name  a.grade a.dept  b.id    b.name
1       lijie1  100.0   10      10      IT1
2       lijie2  90.0    20      20      IT2
3       lijie3  60.0    10      NULL    NULL
4       lijie4  80.0    10      NULL    NULL
5       lijie5  70.0    20      NULL    NULL

条件放在where上面:

select a.id,a.name,a.grade,a.dept,b.id,b.name from tableA a left join tableB b where a.dept=b.id and a.grade>80;

where结果为:

a.id    a.name  a.grade a.dept  b.id    b.name
1       lijie1  100.0   10      10      IT1
2       lijie2  90.0    20      20      IT2

区别:
onwhere 在筛选条件的时候,on 会显示所有满足 | 不满足条件的数据而 where 只显示满足条件的数据。

【更新】
原因是没加on的话两张表是笛卡尔积,后面用where筛选出来复合条件的数据。
on后面加关联条件,可以加上where对关联出的数据进行一个筛选显示。


2、两张表right join且查询分数大于80分的数据

条件放在on上:

select a.id,a.name,a.grade,a.dept,b.id,b.name from tableA a right join tableB b on a.dept=b.id and a.grade>80;

结果为:

a.id    a.name  a.grade a.dept  b.id    b.name
1       lijie1  100.0   10      10      IT1
2       lijie2  90.0    20      20      IT2

条件放在where上:

select a.id,a.name,a.grade,a.dept,b.id,b.name from tableA a right join tableB b where a.dept=b.id and a.grade>80;

结果为:

a.id    a.name  a.grade a.dept  b.id    b.name
1       lijie1  100.0   10      10      IT1
2       lijie2  90.0    20      20      IT2

区别:无


3、两张join且同时查询分数大于80的数据

条件放在on上:

select a.id,a.name,a.grade,a.dept,b.id,b.name from tableA a join tableB b on a.dept=b.id and a.grade>80;

结果为:

a.id    a.name  a.grade a.dept  b.id    b.name
1       lijie1  100.0   10      10      IT1
2       lijie2  90.0    20      20      IT2

条件放在where上:

select a.id,a.name,a.grade,a.dept,b.id,b.name from tableA a join tableB b where a.dept=b.id and a.grade>80;

结果为:

a.id    a.name  a.grade a.dept  b.id    b.name
1       lijie1  100.0   10      10      IT1
2       lijie2  90.0    20      20      IT2

区别:无


4、两张full join且同时查询分数大于80的数据

条件放在on上:

select a.id,a.name,a.grade,a.dept,b.id,b.name from tableA a full join tableB b on a.dept=b.id and a.grade>80;

结果为:

a.id    a.name  a.grade a.dept  b.id    b.name
4       lijie4  80.0    10      NULL    NULL
3       lijie3  60.0    10      NULL    NULL
1       lijie1  100.0   10      10      IT1
5       lijie5  70.0    20      NULL    NULL
2       lijie2  90.0    20      20      IT2

条件放在where上:

select a.id,a.name,a.grade,a.dept,b.id,b.name from tableA a full join tableB b where a.dept=b.id and a.grade>80;

结果为:

a.id    a.name  a.grade a.dept  b.id    b.name
1       lijie1  100.0   10      10      IT1
2       lijie2  90.0    20      20      IT2

区别:
onwhere 在筛选条件的时候,on 会显示所有满足 | 不满足条件的数据而 where 只显示满足条件的数据。


4中join区别的结论:

在on条件下
join 内连接: 筛选条件严格,只要不满足条件的这一项数据就不会显示出来,不论是哪个表的这一行数据-等值连接。

left join 左外连接: 左外连接就是在等值连接的基础上加上主表中的未匹配数据。

right join 右外连接: 右外连接是在等值连接的基础上加上被连接表的不匹配数据 。

full join 满外连接: 全外连接是在等值连接的基础上将左表和右表的未匹配数据都加上。

PS:

在这里我也不清楚为什么我右表的数据会显示NULL,按理说应该显示数据内容的。

where条件免疫,所有的join类型都按照内连接处理。


on与where的区别:

on对join类型的改变而会有反应而where没有,只是当个连接作用对where来说。

### HiveJOIN 的不等条件实现方法 在 Hive 查询中,默认情况下 `JOIN` 操作仅支持基于相等条件的连接,即 `ON` 子句中的条件必须是两个列之间的严格相等关系。然而,在某些场景下可能需要实现基于不等条件的连接逻辑。以下是几种常见的解决方案: #### 方法一:使用笛卡尔积配合 WHERE 过滤 可以通过先执行全量笛卡尔积(Cross Join),然后再利用 `WHERE` 条件筛选满足不等条件的数据。这种方法虽然简单直观,但由于会产生大量的中间数据,性能通常较差。 ```sql SELECT * FROM table_a a CROSS JOIN table_b b WHERE a.col1 < b.col2; ``` 此方法适用于小型的情况,但在处理大规模数据时可能会导致内存溢出或其他性能瓶颈[^2]。 #### 方法二:嵌套子查询法 为了避免笛卡尔积带来的性能问题,可以采用嵌套子查询的方式来实现不等条件的连接。具体做法是将涉及不等条件的部分封装到一个子查询中,并在外层通过标准的 `LEFT JOIN` 或其他形式完成最终的结果组合。 假设我们需要从两张 `table_a` `table_b` 中找到所有满足 `a.col1 >= b.col2` 的记录,则 SQL 可以这样编写: ```sql WITH filtered_b AS ( SELECT col2, other_columns... FROM table_b WHERE EXISTS ( SELECT 1 FROM table_a a WHERE a.col1 >= b.col2 -- 不等条件在此处应用 ) ) SELECT a.*, fb.* FROM table_a a LEFT JOIN filtered_b fb ON a.some_key = fb.some_key; ``` 这种方式能够有效减少不必要的计算开销,同时保留了左连接的特点——即使右侧无匹配项也能保持左侧原始记录完整[^3]。 #### 方法三:模拟 FULL OUTER JOIN 行为 当需求涉及到多个维度或者更复杂的业务场景时,还可以考虑借助 `FULL OUTER JOIN` 结合额外的过滤规则来达成目标效果。不过需要注意的是,Hive 并未原生提供完整的 full outer join 功能;我们往往得依靠 union all 手动拼凑出来类似的结构。 例如下面这个例子展示了如何用 union all 构建近似于 full outer join 的行为模式: ```sql -- 部分 A-B 关联部分 INSERT INTO result_table PARTITION(partition_col='value') SELECT coalesce(a.key_field,b.key_field), ... , CASE WHEN a.key_field IS NOT NULL THEN 'A' ELSE 'B' END as source_flag FROM table_a a FULL OUTER JOIN table_b b ON a.common_id = b.common_id; -- 单独补充仅有 B 而没有对应 A 记录的情形 INSERT INTO result_table PARTITION(partition_col='value') SELECT b.key_field,...,'ONLY_B' FROM table_b b LEFT ANTI JOIN table_a a ON a.common_id=b.common_id ; ``` 上述脚本片段里包含了两步主要操作:第一步实现了常规意义上的双侧联合检索;第二部则进一步追加那些纯粹属于右方却没有任何左边映射的对象实例[^4]。 --- ### 总结 以上介绍了三种不同的策略用于解决 Hive 数据库环境下无法直接达非平等约束下的多互联难题。每种方案都有其适用范围以及局限之处,实际项目开发过程中应综合考量各方面因素选取最优解。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值