`
scholers
  • 浏览: 614757 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

HIVE 中内连接(JOIN ON)与LEFT SEMI JOIN查询结果不一致的分析

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

select
           a.bucket_id,
        a.search_type,
            a.level1,
        a.name1,
        a.level2,
        a.name2,
        cast((a.alipay_fee) as double) as zhuliu_alipay,
        cast(0 as double) as total_alipay
        from tmall_data_fdi_search_zhuliu_alipay_cocerage_bucket_1 a
     left semi join
     tmall_data_fdi_dim_main_auc b
     on (a.level2 = b.cat_id2
         and a.brand_id = b.brand_id
       and b.cat_id2 > 0
         and b.brand_id > 0
         and b.max_price = 0
     )

3121 条
写法二:
select
           a.bucket_id,
        a.search_type,
            a.level1,
        a.name1,
        a.level2,
        a.name2,
        cast((a.alipay_fee) as double) as zhuliu_alipay,
        cast(0 as double) as total_alipay
        from tmall_data_fdi_search_zhuliu_alipay_cocerage_bucket_1 a
     join   tmall_data_fdi_dim_main_auc b
     on (a.level2 = b.cat_id2
         and a.brand_id = b.brand_id)
  where  b.cat_id2 > 0
         and b.brand_id > 0
         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是对等的,但是在上述情况下会出现重复记录。大家以后可要小心。
2
0
分享到:
评论
4 楼 dacoolbaby 2013-04-27  
这个写法有问题。。。过滤数据要在结果集里面进行。。
3 楼 michaellou 2012-11-01  
tb现在真的是全民玩数据啊,哈哈
2 楼 scholers 2012-11-01  
michaellou 写道
tmall_data_fdi_dim_main_auc

tmall?? 天猫?

呵呵
1 楼 michaellou 2012-11-01  
tmall_data_fdi_dim_main_auc

tmall?? 天猫?

相关推荐

Global site tag (gtag.js) - Google Analytics