Hive中的explode使用全解

知乎 · · 1877 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

本节主要介绍explode和posexplode函数的使用。

1、数据介绍
主要包括三列,分别是班级、姓名以及成绩,数据表名是default.classinfo。


2、单列Explode
首先来看下最基本的,我们如何把student这一列中的数据由一行变成多行。这里需要使用split和explode,并结合lateral view实现。代码如下:

select
    class,student_name
from
    default.classinfo
    lateral view explode(split(student,',')) t as student_name

结果如下:


3、单列Posexplode
接下来,我们想要给每个同学来一个编号,假设编号就按姓名的顺序,此时我们要用到另一个hive函数,叫做posexplode,代码如下:

select
    class,student_index + 1 as student_index,student_name
from
    default.classinfo
    lateral view posexplode(split(student,',')) t as student_index,student_name;


这里select时对编号+1主要是因为编号是从0开始的,结果如下:


4、多列Explode
好了,我们继续前进。这次我们想基于两列explode,同时能够使学生和其成绩能够匹配,即期望的效果如下:


显然我们要对两列进行explode,先试试行不行:

select
    class,student_name,student_score
from
    default.classinfo
    lateral view explode(split(student,',')) sn as student_name
    lateral view explode(split(score,',')) sc as student_score


结果如下:


好像是不太行,如果我们分别对两列进行explode的话,假设每列都有三个值,那么最终会变成3 * 3 = 9行。但我们想要的结果只有三行。此时我们可以进行两次posexplode,姓名和成绩都保留对应的序号,即使变成了9行,我们通过where条件只保留序号相同的行即可。代码如下:

select
    class,student_name,student_score
from
    default.classinfo
    lateral view posexplode(split(student,',')) sn as student_index_sn,student_name
    lateral view posexplode(split(score,',')) sc as student_index_sc,student_score
where
    student_index_sn = student_index_sc;


此时结果就对了:


好了,到这里本应该就结束了,假设我们又想对同学的成绩进行一下排名该怎么做呢?当然是借助rank函数啦(row_number函数对于相同的成绩也会赋予不同的排名,所以我们选择rank函数,关于二者的区别我们后续再细讲):

select
    class,
    student_name,
    student_score,
    rank() over(partition by class order by student_score desc) as student_rank
from
    default.classinfo
    lateral view posexplode(split(student,',')) sn as student_index_sn,student_name
    lateral view posexplode(split(score,',')) sc as student_index_sc,student_score
where
    student_index_sn = student_index_sc
    order by class,student_rank;


结果符合我们预期:

本文转自:网页链接


本文来自:知乎

感谢作者:知乎

查看原文:Hive中的explode使用全解

1877 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传