在一般的需求中,我们是根据某一列来求中位数,这种情况可以看我的这篇博客 —— Hive 之中位数。
今天在公司项目中遇到了需要按行求中位数的情况,于是通过这篇博客记录一下我的解决方法。
测试数据建立:
create database if not exists test;
drop table if exists test.company;
create table test.company(
id int,
data1 int,
data2 int,
data3 int);
insert into test.company values(1,10,20,30),(2,40,50,60),(3,70,80,90),(4,100,110,120),(5,130,140,150);
需求介绍:
在 Hive 中我建立了 test.company
测试表,需要求出每一行 data1,data2,data3
的中位数。
需求实现:
我们先将多个字段数据的行转换为列。
select
id,
tmp.data
from
test.company
lateral view
explode(array(data1,data2,data3)) tmp as data;
执行后得到如下样式的数据:
然后分组计算每个 id
的中位数。
select
id,
cast(percentile(data,0.5) as int) median_data
from
(select
id,
tmp.data
from
test.company
lateral view
explode(array(data1,data2,data3)) tmp as data)t1
group by
id;
最终结果如下:
需求总结:
首先我们将多个字段通过 array
构成一个数组,然后通过 explode
方法将该数组打散,转换成列,最后分组计算中位数,解决需求。
这个问题最终还是得将行转为列来做,目前我就想到这种思路,有其他更好的方法可以一起讨论。