zoukankan      html  css  js  c++  java
  • Hive不支持非相等的join

    由于 hive 与传统关系型数据库面对的业务场景及底层技术架构都有着很大差异,因此,传统数据库领域的一些技能放到 Hive 中可能已不再适用。关于 hive 的优化与原理、应用的文章,前面也陆陆续续的介绍了一些,但大多都偏向理论层面,本文就介绍一个实例,从实例中一步步加深对 hive 调优的认识与意识。

    1、需求

    需求我做了简化,很简单,两张表做个 join,求指定城市,每天的 pv,用传统的 RDBMS SQL 写出来就这样的:

    SELECT t.statdate,
      c.cname,
      count(t.cookieid)
    FROM tmpdb.city c
    JOIN ecdata.ext_trackflow t ON (t.area1= c.cname
                OR t.area2 =c.cname
                OR t.area3 = c.cname)
    WHERE t.statdate>='20140818' and t.statdate<='20140824'
      AND platform='pc'
    GROUP BY t.statdate,
        c.cname;

    怎么样?根据 SQL 看懂需求没问题吧?

    2、非等值 join 问题

    然后把这条 SQL 贴到 hive 中去执行,然后你会发现报错了:

    FAILED: SemanticException [Error 10019]: Line 5:32 OR not supported in JOIN currently 'cname'

    这是因为 hive 受限于 MapReduce 算法模型,只支持 equi-joins(等值 join),要实现上述的非等值 join,你可以采用笛卡儿积( full Cartesian product )来实现:

    SELECT t.statdate,
      c.cname,
      count(t.cookieid)
    FROM tmpdb.city c
    JOIN ecdata.ext_trackflow t
    WHERE t.statdate>='20140818'
      AND t.statdate<='20140824'
      AND platform='pc'
      AND (t.area1= c.cname
      OR t.area2 =c.cname
      OR t.area3 = c.cname)
    GROUP BY t.statdate,
        c.cname;

    然后再拿着这条语句执行下。

    改写非等值 join:union all

    既然不允许非等值 join,那我们换一下思路,多个子查询 union all,然后汇总:

    SELECT dt,
           name,
           count(cid)
    FROM
      (SELECT t.statdate dt,
              c.cname name,
              t.cookieid cid
       FROM tmpdb.city c
       JOIN ecdata.ext_trackflow t ON t.area1 =c.cname
       WHERE t.statdate>='20140818'
         AND t.statdate<='20140824'
         AND platform='pc'
       UNION ALL SELECT t.statdate dt,
         c.cname name,
         t.cookieid cid
       FROM tmpdb.city c
       JOIN ecdata.ext_trackflow t ON t.area2 =c.cname
       WHERE t.statdate>='20140818'
         AND t.statdate<='20140824'
         AND platform='pc'
       UNION ALL SELECT t.statdate dt,
         c.cname name,
         t.cookieid cid
       FROM tmpdb.city c
       JOIN ecdata.ext_trackflow t ON t.area3 =c.cname
       WHERE t.statdate>='20140818'
         AND t.statdate<='20140824'
         AND platform='pc') tmp_trackflow
    GROUP BY dt,
             name;

    造成这个的原因是子查询出来有字段相同,可以改字段方式解决

    select *
    from
    (select si.name as siname,gsi.name as gsiname from student_infos si join good_student_infos gsi on si.name = gsi.name ) st;

    如果不出现重复字段不会报错

    联合查询代替hive不能join非相等查询问题

  • 相关阅读:
    axios基础用法
    CSS盒子模型
    前端跨域问题解决方案
    跨域-iframe
    swagger UI配置
    React安装和启动
    React 学习笔记
    redis学习笔记
    10个排序算法,待更新
    docker常用命令,持续更新。。。
  • 原文地址:https://www.cnblogs.com/yaohaitao/p/5814775.html
Copyright © 2011-2022 走看看