Hive函式(內建函式+自定義標準函式UDF)

小財迷,嘻嘻發表於2020-09-23

Hive提供大量內建函式供開發者使用,也可以自定義函式使用

1、內建函式:

標準函式(字元函式、轉換函式、數學函式、日期函式、集合函式、條件函式 )
聚合函式
表生成函式

常用內建函式如下:
在這裡插入圖片描述
在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

2、自定義函式

UDF:自定義標準函式
UDAF:自定義聚合函式
UDTF:自定義表生成函式

自定義標準函式UDF步驟:

1、java繼承UDF類編寫udf函式(evaluate())(一個類一個方法)
2、打fat包(包括所有依賴檔案)
3、把jar包放到linux上
–臨時udf函式
4、在hive命令列中使用add jar jar包路徑即可載入到臨時系統中
5、create temporary function 函式名 as ‘方法的全類名’
–永久udf函式
4、在linux命令列使用hdfs命令把jar上傳到hdfs的路徑
5、create function 函式名 as ‘方法的全類名’ using jar ‘jar包的全路徑’

示例:
1、需求:輸入字串轉成大寫

package cn.kgc.kb09.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
/**
* @Author
* @Date 2020/9/22
* @Description 功能:轉大寫
*/
public class TestUDF extends UDF {
    public Text evaluate(Text str){
        if (null==str){
            return null;
        }
        return new Text(str.toString().toUpperCase());
    }
//    public static void main(String[] args) {
//        TestUDF tu= new TestUDF();
//        Text rst=tu.evaluate(new Text(args[0]));
//        System.out.println(rst);
//    }
}

2、打jar包,注意是fat包,包括依賴檔案,jar包名為:20200922testudf.jar;
3、將jar包拖拽到Linux系統;
為防止在第五步建立臨時函式時出現以下問題,需要進行相關操作
在這裡插入圖片描述
在Linux命令列輸入:

#下載zip包
yum install zip
#以下命令會刪除先前jar的簽名檔案(-d後面引數是自己jar包的名字)
zip -d 20200922testudf.jar 'META-INF/.SF' 'META-INF/.RSA' 'META-INF/*SF'                                                                                   

4、(臨時udf函式)在hive命令列中使用add jar jar包路徑即可載入到臨時系統中;

add jar /root/20200922testudf.jar;

5、hive命令列中create function 函式名 as ‘方法的全類名’ using jar ‘jar包的全路徑’,
出現ok表示成功。

create temporary function atoA as 'cn.kgc.kb09.udf.TestUDF';

6、呼叫函式

select atoA(abcdefg)

結果為:ABCDEFG

4、(永久udf函式)在linux命令列使用hdfs命令把jar上傳到hdfs的路徑

hdfs dfs -put20200922testudf.jar /apps/hive/functions

5、在hive命令列中create function 函式名 as ‘方法的全類名’ using jar ‘jar包的全路徑’

create function aToA2 as 'cn.kgc.kb09.udf.TestUDF' using jar 'hdfs://hadoop20:9000/apps/hive/functions/20200922testudf.jar';

6、呼叫函式

select atoA2(abc)

結果為:ABCDEFG

練習1:在一個時間基礎上,進行小時的加減,得到新的時間

package cn.kgc.kb09.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * @Author
 * @Date 2020/9/22
 * @Description 在一個時間基礎上,進行小時的加減,得到新的時間
 */
public class AddHour extends UDF {
    public Text evaluate(Text beforeDate, IntWritable hours) throws Exception {
        String d=beforeDate.toString();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = sdf.parse(d);
        String rst = sdf.format(new Date(date.getTime() + hours.get() * 60 * 60 * 1000));
        return new Text(rst);
    }
//    public static void main(String[] args) throws Exception {
//        AddHour ah=new AddHour();
//        Text t=new Text("2020-09-22 10:20:00");
//        IntWritable iw=new IntWritable(3);
//        System.out.println(ah.evaluate(t, iw));
//    }
}

練習2:計算兩個時間的時間差(小時)

package cn.kgc.kb09.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * @Author
 * @Date 2020/9/22
 * @Description 計算兩個時間的時間差(小時)
 */
public class HourDiff extends UDF {
    public IntWritable evaluate(Text date1,Text date2) throws Exception {
        String d1= date1.toString();
        String d2 = date2.toString();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date dt1 = sdf.parse(d1);
        Date dt2 = sdf.parse(d2);
        long diff = dt1.getTime() - dt2.getTime();
        int rst = (int)diff / 1000 / 60 / 60;
        return new IntWritable(rst);
    }
//    public static void main(String[] args) throws Exception {
//        HourDiff hd =new HourDiff();
//        System.out.println(hd.evaluate(new Text("2020-09-21 12:00:00"),
//                new Text("2020-09-22 23:00:00")));
//    }
}

相關文章