HIVE 中内连接(join on )与left semi join 查询结果不一致的分析(两者区别)

2024-06-10 04:32

本文主要是介绍HIVE 中内连接(join on )与left semi join 查询结果不一致的分析(两者区别),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、第一种讲解

LEFT SEMI JOIN (左半连接)是 IN/EXISTS 子查询的一种更高效的实现

Hive 当前没有实现 IN/EXISTS 子查询,所以可以用 LEFT SEMI JOIN 重写你的子查询语句

示例

可以改写为

特点

1、left semi join 的限制是, JOIN 子句中右边的表只能在 ON 子句中设置过滤条件,在 WHERE 子句、SELECT 子句或其他地方过滤都不行。

2、left semi join 是只传递表的 join key 给 map 阶段,因此left semi join 中最后 select 的结果只许出现左表。

3、因为 left semi join 是 in(keySet) 的关系,遇到右表重复记录,左表会跳过,而 join 则会一直遍历。这就导致右表有重复值得情况下 left semi join 只产生一条,join 会产生多条,也会导致 left semi join 的性能更高。 

比如以下A表和B表进行 join 或 left semi join,然后 select 出所有字段,结果区别如下:

二、第二种讲解

重点:由于子表(tmall_data_fdi_dim_main_auc)中存在重复的数据,当使用JOIN ON的时候,A,B表会关联出两条记录,应为ON上的条件符合; 
而是用LEFT SEMI JOIN 当A表中的记录,在B表上产生符合条件之后就返回,不会再继续查找B表记录了,所以如果B表有重复,也不会产生重复的多条记录。 

由于HIVE中都是等值连接,在JOIN使用的时候,有两种写法在理论上是可以达到相同的效果的,但是由于实际情况的不一样,子表中数据的差异导致结果也不太一样。 
  
写法一: 

Java代码 

  1. select  
  2.            a.bucket_id,  
  3.         a.search_type,  
  4.             a.level1,  
  5.         a.name1,  
  6.         a.level2,  
  7.         a.name2,  
  8.         cast((a.alipay_fee) as double) as zhuliu_alipay,  
  9.         cast(0 as double) as total_alipay  
  10.         from tmall_data_fdi_search_zhuliu_alipay_cocerage_bucket_1 a  
  11.      left semi join  
  12.      tmall_data_fdi_dim_main_auc b  
  13.      on (a.level2 = b.cat_id2  
  14.          and a.brand_id = b.brand_id  
  15.        and b.cat_id2 > 0  
  16.          and b.brand_id > 0  
  17.          and b.max_price = 0  
  18.      )  


3121 条 


写法二: 
Java代码 

  1. select  
  2.            a.bucket_id,  
  3.         a.search_type,  
  4.             a.level1,  
  5.         a.name1,  
  6.         a.level2,  
  7.         a.name2,  
  8.         cast((a.alipay_fee) as double) as zhuliu_alipay,  
  9.         cast(0 as double) as total_alipay  
  10.         from tmall_data_fdi_search_zhuliu_alipay_cocerage_bucket_1 a  
  11.      join   tmall_data_fdi_dim_main_auc b  
  12.      on (a.level2 = b.cat_id2  
  13.          and a.brand_id = b.brand_id)  
  14.   where  b.cat_id2 > 0  
  15.          and b.brand_id > 0  
  16.          and b.max_price = 0  



结果是:3142 


这两种写法带来的值居然不是相等的,我一直以为理解这两种方式的写法是一样的, 
但是统计的结果却是不一样的。 
目前还没有搞清楚是什么原因,谁能那个搞清楚呢。 


经过一层一层的查找,发现是由于子表(tmall_data_fdi_dim_main_auc)中存在重复的数据,当使用JOIN ON的时候,A,B表会关联出两条记录,应为ON上的条件符合; 
而是用LEFT SEMI JOIN 当A表中的记录,在B表上产生符合条件之后就返回,不会再继续查找B表记录了,所以如果B表有重复,也不会产生重复的多条记录。 

大多数情况下JOIN ON 和left semi on是对等的,但是在上述情况下会出现重复记录。大家以后可要小心。

这篇关于HIVE 中内连接(join on )与left semi join 查询结果不一致的分析(两者区别)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1047216

相关文章

Mybatis 传参与排序模糊查询功能实现

《Mybatis传参与排序模糊查询功能实现》:本文主要介绍Mybatis传参与排序模糊查询功能实现,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、#{ }和${ }传参的区别二、排序三、like查询四、数据库连接池五、mysql 开发企业规范一、#{ }和${ }传参的

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd

Ubuntu中远程连接Mysql数据库的详细图文教程

《Ubuntu中远程连接Mysql数据库的详细图文教程》Ubuntu是一个以桌面应用为主的Linux发行版操作系统,这篇文章主要为大家详细介绍了Ubuntu中远程连接Mysql数据库的详细图文教程,有... 目录1、版本2、检查有没有mysql2.1 查询是否安装了Mysql包2.2 查看Mysql版本2.

Python3.6连接MySQL的详细步骤

《Python3.6连接MySQL的详细步骤》在现代Web开发和数据处理中,Python与数据库的交互是必不可少的一部分,MySQL作为最流行的开源关系型数据库管理系统之一,与Python的结合可以实... 目录环境准备安装python 3.6安装mysql安装pymysql库连接到MySQL建立连接执行S

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

分辨率三兄弟LPI、DPI 和 PPI有什么区别? 搞清分辨率的那些事儿

《分辨率三兄弟LPI、DPI和PPI有什么区别?搞清分辨率的那些事儿》分辨率这个东西,真的是让人又爱又恨,为了搞清楚它,我可是翻阅了不少资料,最后发现“小7的背包”的解释最让我茅塞顿开,于是,我... 在谈到分辨率时,我们经常会遇到三个相似的缩写:PPI、DPI 和 LPI。虽然它们看起来差不多,但实际应用

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3