有没有办法在Hive中转置数据?

时间:2013-09-04 22:41:14

标签: hive bigdata transpose

Hive中的数据可以转置吗?如同,行成为列,列是行?如果没有直接功能,有没有办法在几个步骤中完成?

我有一张这样的表:

 | ID   |   Names   |  Proc1   |   Proc2 |  Proc3  |
 | 1    |    A1     |   x      |   b     |  f      |
 | 2    |    B1     |   y      |   c     |  g      |
 | 3    |    C1     |   z      |   d     |  h      |
 | 4    |    D1     |   a      |   e     |  i      |

我希望它是这样的:

 | A1   |   B1   |  C1   |   D1 |  
 | x    |    y   |   z   |   a  |
 | b    |    c   |   d   |   e  |
 | f    |    g   |   h   |   i  |

我一直在查找其他相关问题,他们都提到使用横向视图和爆炸,但有没有办法有选择地选择横向(ly)视图(ing)和爆炸(ing)的列?

此外,实现我想做的事情的粗略过程可能是什么?请帮帮我。谢谢!

编辑:我一直在阅读此链接:https://cwiki.apache.org/Hive/languagemanual-lateralview.html,它向我展示了我想要实现的目标的一半。链接中的第一个示例基本上是我想要的,除了我不希望行重复并希望它们作为列名。关于如何将数据传递到表单的任何想法,如果我执行explode,它将导致我想要的输出,或者另一种方式,即explode首先导致另一个步骤然后会导致我想要的输出表。再次感谢!

2 个答案:

答案 0 :(得分:3)

我不知道在蜂巢中开箱即用,对不起。你接近爆炸等等,但我认为它不能完成任务。

总的来说,从概念上讲,我认为在不知道目标表的列将提前是什么的情况下进行转置是很困难的。这是真的,特别是对于配置单元,因为元数据与数据库中的列数,类型,名称等有关 - 元数据库。而且,一般情况下都是如此,因为事先不知道列,需要某种内存中的数据保存(好吧,确定有溢出),用户可能需要注意不要溢出内存等等(就像动态一样)分配在蜂巢中。)

无论如何,长话短说,如果你事先知道目的地表的栏目,生活是美好的。据我所知,在hive本身没有set命令,但是你可以使用一堆if子句和case语句(丑陋我知道,但这就是我过去做过同样的事情) select子句用于转置数据。类似SQL - How to transpose?

的内容

请告诉我它是怎么回事!

答案 1 :(得分:1)

正如Mark所指出的那样,在Hive中没有简单的方法可以做到这一点,因为PIVOT在Hive中没有出现,并且当你有多个值时,在尝试使用case / when'时'也可能遇到问题(PROC1,PROC2,PROC3)。

至于测试目的,您可以尝试不同的方法:

select v, o1, o2, o3 from (
  select k, 
         v,
         LEAD(v,3) OVER() as o1,
         LEAD(v,6) OVER() as o2,
         LEAD(v,9) OVER() as o3
  from (select transform(name,proc1,proc2,proc3) using 'python strm.py' AS (k, v) 
    from input_table) q1
) q2 where k = 'A1';

其中 strm.py

import sys

for line in sys.stdin:
  line = line.strip()
  name, proc1, proc2, proc3 = line.split('\t')
  print '%s\t%s' % (name, proc1)
  print '%s\t%s' % (name, proc2)
  print '%s\t%s' % (name, proc3)

这里的技巧是在map阶段使用python脚本,它将行的每一列作为不同的行发出。然后每三分之一(因为我们有3个proc列)行将形成我们通过向前偷看(领先)得到的结果行。

然而,这个查询完成了这项工作,它的缺点是随着输入的增长,你需要查看查询中可能导致性能下降的下一个第3个元素。无论如何,您可以进行评估以进行测试。