hive使用UDTF函数实现单列转多行输出

本文介绍如何利用Hive的UDTF(User Defined Table Generating Function)实现数组元素的拆分及生成连续数字的功能。提供了使用explode函数处理数组的示例,并详细展示了自定义UDTF函数的Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hive本身提供explode函数实现这种功能,explode方法接受一个数值作为输入,将每个数组元素作为一行输出。


比如:

pageid  paged

page1   a,b,c

要转换成

page1 a

page1 b

page1 c

select pageid,p from test lateral view explode(split(paged,',')) adtable as p;


通过split拆成多个元素的集合,再通过split打散成多行,lateral view作用是解决explode这种UDTF函数拆成的数据不能与其他字段共同服务问题

以上例子来自:http://www.07net01.com/linux/hivexingliezhuanhuanzongjie_654296_1381813421.html

                            http://blog.youkuaiyun.com/inte_sleeper/article/details/7196114


但本人在使用split分割时总是出现问题,split的正则一直匹配错误

于是转去研究使用hive提供的自定义UDTF函数的方式实现,在这感谢两位博客的文章分享:

http://blog.sina.com.cn/s/blog_6ff05a2c0100tpi4.html

http://blog.youkuaiyun.com/cheersu/article/details/8333045

ORACLE中生成从1到n的连续数字的方法很多,最简单的一种是:

select level from dual connect by level<=5;

        LEVEL
----------
                  1
              2
              3
              4
              5
 
使用UDTF写出来的函数进行查询:
hive> select serial(5) as col1 from dual;
OK
1
2
3
4
5
 
或者使用lateral view进行查询:
hive> select T.col1 from dual lateral view serial(5) T as col1;
OK
1
2
3
4
5
 
提供一下java代码,仅供参考:
 
package com.hadoopbook.hive;
import java.util.ArrayList;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthExcepti on;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspector Factory;
public class UDTFSerial extends GenericUDTF {
 
   Object[] result = new Object[1];
 
   @Override
   public void close() throws HiveException {
   }
 
   @Override
   public StructObjectInspector initialize(ObjectInspector[] args)
                   throws UDFArgumentException {
           if (args.length != 1) {
                   throw new UDFArgumentLengthExcepti on("UDTFSerial takes only one argument");
           }
           if (!args[0].getTypeName().equals("int")) {
            throw new UDFArgumentException("UDTFSerial only takes an integer as a parameter");
               }
           ArrayList<String> fieldNames = new ArrayList<String>();
           ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();
           fieldNames.add("col1");
           fieldOIs.add(PrimitiveObjectInspector Factory.javaIntObjectInspector);
         
           return ObjectInspectorFactory.getStandardStructObjectI nspector(fieldNames,fieldOIs);
   }
 
   @Override
   public void process(Object[] args) throws HiveException {
     try
     {
       int n = Integer.parseInt(args[0].toString());
       for (int i=0;i<n;i++)
       {
         result[0] = i+1;
         forward(result);
       }
     }
     catch (Exception e) { 
       throw new HiveException("UDTFSerial has an exception");
     }
   }
}
另:在使用UDTF函数时我是只能在lateral view中使用否则报UDTF's are not supported outside the SELECT clause, nor nested in expressions错误

参考: http://issues.apache.org/jira/browse/HIVE-1370 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值