目录
一、系统内置函数
日期类
unix_timestamp:返回指定时间的时间戳
select unix_timestamp('2021-12-23 12-51-25','yyyy-MM-dd HH-mm-ss');
from_unixtime:将时间戳转化为具体时间 select from_unixtime(1640263885);
current_date:当前日期 select current_date;
date_formate: 转换格式 select date_format('2021-12-27','yyyy-MM')
current_timestamp:当前的日期加时间带毫秒
to_date:抽取日期部分 select to_date('2021-12-23 13-59-56');
year:获取年 select year('2021-12-23 13-59-56');
month:获取月
day:获取日
hour:获取时
minute:获取分
second:获取秒
weekofyear:当前时间是一年中的第几周 select weekofyear('2021-12-31');
dayofmonth:当前时间是一个月中的第几天 select dayofmonth('2021-12-23');
months_between: 两个日期间的月份 select months_between('2021-12-23','2022-2-5');后面减前面
add_months:日期加减月 select add_months('2021-10-2',-2);
datediff:两个日期相差的天数 select datediff('2021-2-5','2021-12-6'); 前面减后面
date_add:日期加天数 select date_add('2021-8-8',5);
date_sub:日期减天数 select date_add('2021-8-8',-5);
last_day:日期的当月的最后一天 select last_day('2021-12-5');
取整类:
round: 四舍五入 select round(2.3);
ceil: 向上取整
floor: 向下取整
字符串操作函数
upper: 转大写 select upper('ssss');
lower: 转小写
length: 长度 select length('ssss');
trim: 前后去空格 select trim(' ls ');
lpad: 向左补齐,到指定长度 select lpad('ls',5,'@');
rpad: 向右补齐,到指定长度
regexp_replace:替换 select regexp_replace('ababab','b','c');
集合操作
size: 集合中元素的个数
map_keys: 返回map中的key
map_values: 返回map中的value
array_contains: 判断array中是否包含某个元素
sort_array: 将array中的元素排序
二、常用内置函数
1.空字段赋值
NVL:给值为NULL的数据赋值,它的格式是NVL( value,default_value)。它的功能是如果value为NULL,则NVL函数返回default_value的值,否则返回value的值,如果两个参数都为NULL ,则返回NULL。
select id,nvl(id, -1) from stu; //如果id为NULL,则返回-1
2.case语句
具体格式:CASE WHEN THEN ELSE END
需求:
name | dept_id | sex |
悟空 | A | 男 |
大海 | A | 男 |
宋宋 | B | 男 |
凤姐 | A | 女 |
婷姐 | B | 女 |
婷婷 | B | 女 |
得到:
+------------+-------+---------+
| t.dept_id | male | female |
+------------+-------+---------+
| A | 2 | 1 |
| B | 1 | 2 |
+------------+-------+---------+
步骤:
select
dept_id,
case when '男' then 1 else 0 end male,
case when '女' then 1 else 0 end female,
from emp_sex
+----------+-------+---------+
| dept_id | male | female |
+----------+-------+---------+
| A | 1 | 0 |
| A | 1 | 0 |
| B | 1 | 0 |
| A | 0 | 1 |
| B | 0 | 1 |
| B | 0 | 1 |
+----------+-------+---------+
select
t.dept_id,
sum(t.male) male,
sum(t.female) female
from (select
dept_id,
case sex when '男' then 1 else 0 end,
case sex when '女' then 1 else 0 end
from emp_sex) t
group by t.dept_id;
+------------+-------+---------+
| t.dept_id | male | female |
+------------+-------+---------+
| A | 2 | 1 |
| B | 1 | 2 |
+------------+-------+---------+
select
dept_id,
sum(case sex when '男' then 1 else 0 end ) male,
sum(case sex when '女' then 1 else 0 end ) female
from emp_sex
group by dept_id;
用if
select
dept_id,
sum(if(sex='男',1,0)) male,
sum(if(sex='女',1,0)) female
from emp_sex
group by dept_id
3.行转列
函数:CONCAT(string A, string B) 连接字符串
CONCAT_WS(separator, str1, str2,...) 用separator连接字符串 注:注意:CONCAT_WS must be "string or array<string>"
COLLECT_SET() 去重,产生array类型字段
COLLECT_LIST() 不去重,产生array类型字段
需求:
name | constellation | blood_type |
孙悟空 | 白羊座 | A |
大海 | 射手座 | A |
宋宋 | 白羊座 | B |
猪八戒 | 白羊座 | A |
凤姐 | 射手座 | A |
苍老师 | 白羊座 | B |
得到:
射手座,A 大海|凤姐
白羊座,A 孙悟空|猪八戒
白羊座,B 宋宋|苍老师
步骤:
select
concat(constellation,',',blood_type),
name
from person_info
select
t.a,
concat_ws('|',collect_set(t.name))
from (select
concat(constellation,',',blood_type) a,
name
from person_info) t
group by t.a
+--------+----------+
| t.a | _c1 |
+--------+----------+
| 射手座,A | 大海|凤姐 |
| 白羊座,A | 孙悟空|猪八戒 |
| 白羊座,B | 宋宋|苍老师 |
+--------+----------+
select
concat(constellation,',',blood_type),
concat_ws('|',collect_list(name))
from person_info
group by concat(constellation,',',blood_type)
4.列转行
函数:
Split(str, s):用分隔符s分割字符串str,转换成array。
EXPLODE():将hive一列中复杂的array或者map结构拆分成多行。
LATERAL VIEW
用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias
解释:lateral view用于和split, explode等UDTF一起使用,它能够将一行数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。
lateral view首先为原始表的每行调用UDTF,UDTF会把一行拆分成一或者多行,lateral view再把结果组合,产生一个支持别名表的虚拟表。
需求:
movie | category |
《疑犯追踪》 | 悬疑,动作,科幻,剧情 |
《Lie to me》 | 悬疑,警匪,动作,心理,剧情 |
《战狼2》 | 战争,动作,灾难 |
得到:
《疑犯追踪》 悬疑
《疑犯追踪》 动作
《疑犯追踪》 科幻
《疑犯追踪》 剧情
《Lie to me》 悬疑
《Lie to me》 警匪
《Lie to me》 动作
《Lie to me》 心理
《Lie to me》 剧情
《战狼2》 战争
《战狼2》 动作
《战狼2》 灾难
步骤:
select
EXPLODE(split(category,','))
from movie_info
+------+
| col |
+------+
| 悬疑 |
| 动作 |
| 科幻 |
| 剧情 |
| 悬疑 |
| 警匪 |
| 动作 |
| 心理 |
| 剧情 |
| 战争 |
| 动作 |
| 灾难 |
+------+
select
movie
from movie_info
+--------------+
| movie |
+--------------+
| 《疑犯追踪》 |
| 《Lie to me》 |
| 《战狼2》 |
+--------------+
select
movie,
category_name
from movie_info
lateral view explode(split(category,',')) tmp as category_name
where category_name = '悬疑';
+--------------+----------------+
| movie | category_name |
+--------------+----------------+
| 《疑犯追踪》 | 悬疑 |
| 《Lie to me》 | 悬疑 |
+--------------+----------------+
select
movie,
category_name
from movie_info
lateral view explode(split(category,',')) tmp as category_name;
+--------------+----------------+
| movie | category_name |
+--------------+----------------+
| 《疑犯追踪》 | 悬疑 |
| 《疑犯追踪》 | 动作 |
| 《疑犯追踪》 | 科幻 |
| 《疑犯追踪》 | 剧情 |
| 《Lie to me》 | 悬疑 |
| 《Lie to me》 | 警匪 |
| 《Lie to me》 | 动作 |
| 《Lie to me》 | 心理 |
| 《Lie to me》 | 剧情 |
| 《战狼2》 | 战争 |
| 《战狼2》 | 动作 |
| 《战狼2》 | 灾难 |
+--------------+----------------+
5.窗口函数
OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化。
CURRENT ROW:当前行
n PRECEDING:往前n行数据
n FOLLOWING:往后n行数据
UNBOUNDED:无边界
UNBOUNDED PRECEDING 前无边界,表示从前面的起点,
UNBOUNDED FOLLOWING后无边界,表示到后面的终点
LAG(col,n,default_val):往前第n行数据
LEAD(col,n, default_val):往后第n行数据
FIRST_VALUE (col,true/false):当前窗口下的第一个值,第二个参数为true,跳过空值
LAST_VALUE (col,true/false):当前窗口下的最后一个值,第二个参数为true,跳过空值
NTILE(n):把有序窗口的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。注意:n必须为int类型。
语法
函数+窗口
函数:代表的计算的逻辑
窗口:表示函数的计算范围 把窗口数据给到函数做计算
函数+over([partition by ...] [order by ...] [窗口子句]) over表示开窗
over 表示开窗 默认有一个窗口大小 就是所有数据
partition by 表示根据字段再划分一个细窗口 相同字段进入同一个细窗口里面 每个窗口之间相互独立 窗口子句对于每个细窗口独立生效
order by 表示窗口内按什么排序 如果只有over 表示直接最大窗口排序 如果有partition by 每个细窗口单独排序
执行顺序
1.over
2.partition
3.order by
4.窗口子句
5.函数
窗口子句默认值:当有order by 但是缺少窗口子句时,范围是上无边界到当前行
当order by 和 窗口子句都缺少时,范围是上无边界到下无边界
不支持窗口子句的函数
rank dense_rank ntile row_number lag lead
注意:
一. 建表的时候
1.partitioned by 表示你创建的表为分区表
2.clustered by 表示你创建表为分桶表
二. 查询语句里排序的四个by
order by 表示全局排序
distribute by 以什么分区 sort by 区内排序字段
cluster by 表示分区排序
三.窗口函数的partition
partition by 表示 更细窗口划分
order by 窗口以什么排序
distribute by sort by 相当于 partition by order by
实例:
jack,2017-01-01,10
tony,2017-01-02,15
jack,2017-02-03,23
tony,2017-01-04,29
jack,2017-01-05,46
jack,2017-04-06,42
tony,2017-01-07,50
jack,2017-01-08,55
mart,2017-04-08,62
mart,2017-04-09,68
neil,2017-05-10,12
mart,2017-04-11,75
neil,2017-06-12,80
mart,2017-04-13,94
具体例子
(1)查询在2017年4月份购买过的顾客及总人数
select
name,
count(*) over(rows between UNBOUNDED PRECEDING and current row)
from business
where month(orderdate)=4
group by name;
+-------+-----------------+
| name | count_window_0 |
+-------+-----------------+
| mart | 1 |
| jack | 2 |
+-------+-----------------+
(2)查询所有月购买过的顾客及总人数(不用窗口函数)
select
date_format(orderdate,'yyyy-MM'),
collect_set(name),
size(collect_set(name))
from business
group by date_format(orderdate,'yyyy-MM');
+----------+------------------+------+
| _c0 | _c1 | _c2 |
+----------+------------------+------+
| 2017-01 | ["jack","tony"] | 2 |
| 2017-02 | ["jack"] | 1 |
| 2017-04 | ["jack","mart"] | 2 |
| 2017-05 | ["neil"] | 1 |
| 2017-06 | ["neil"] | 1 |
+----------+------------------+------+
(3)查询顾客的购买明细及月购买总额
select
name,
orderdate,
cost,
sum(cost)over(partition by month(orderdate))
from business
+-------+-------------+-------+---------------+
| name | orderdate | cost | sum_window_0 |
+-------+-------------+-------+---------------+
| jack | 2017-01-01 | 10 | 205 |
| jack | 2017-01-08 | 55 | 205 |
| tony | 2017-01-07 | 50 | 205 |
| jack | 2017-01-05 | 46 | 205 |
| tony | 2017-01-04 | 29 | 205 |
| tony | 2017-01-02 | 15 | 205 |
| jack | 2017-02-03 | 23 | 23 |
| mart | 2017-04-13 | 94 | 341 |
| jack | 2017-04-06 | 42 | 341 |
| mart | 2017-04-11 | 75 | 341 |
| mart | 2017-04-09 | 68 | 341 |
| mart | 2017-04-08 | 62 | 341 |
| neil | 2017-05-10 | 12 | 12 |
| neil | 2017-06-12 | 80 | 80 |
+-------+-------------+-------+---------------+
(4)上述的场景, 将每个顾客的cost按照日期进行累加
select
name,
orderdate,
cost,
sum(cost)over(partition by name order by orderdate)
from business
+-------+-------------+-------+---------------+
| name | orderdate | cost | sum_window_0 |
+-------+-------------+-------+---------------+
| jack | 2017-01-01 | 10 | 10 |
| jack | 2017-01-05 | 46 | 56 |
| jack | 2017-01-08 | 55 | 111 |
| jack | 2017-02-03 | 23 | 134 |
| jack | 2017-04-06 | 42 | 176 |
| mart | 2017-04-08 | 62 | 62 |
| mart | 2017-04-09 | 68 | 130 |
| mart | 2017-04-11 | 75 | 205 |
| mart | 2017-04-13 | 94 | 299 |
| neil | 2017-05-10 | 12 | 12 |
| neil | 2017-06-12 | 80 | 92 |
| tony | 2017-01-02 | 15 | 15 |
| tony | 2017-01-04 | 29 | 44 |
| tony | 2017-01-07 | 50 | 94 |
+-------+-------------+-------+---------------+
(5)查询顾客购买明细以及上次的购买时间和下次购买时间
select
name,
orderdate,
cost,
lag(orderdate,1,'0000-00-00')over(partition by name order by orderdate),
lead(orderdate,1,'9999-99-99')over(partition by name order by orderdate)
from business
+-------+-------------+-------+---------------+----------------+
| name | orderdate | cost | lag_window_0 | lead_window_1 |
+-------+-------------+-------+---------------+----------------+
| jack | 2017-01-01 | 10 | 0000-00-00 | 2017-01-05 |
| jack | 2017-01-05 | 46 | 2017-01-01 | 2017-01-08 |
| jack | 2017-01-08 | 55 | 2017-01-05 | 2017-02-03 |
| jack | 2017-02-03 | 23 | 2017-01-08 | 2017-04-06 |
| jack | 2017-04-06 | 42 | 2017-02-03 | 9999-99-99 |
| mart | 2017-04-08 | 62 | 0000-00-00 | 2017-04-09 |
| mart | 2017-04-09 | 68 | 2017-04-08 | 2017-04-11 |
| mart | 2017-04-11 | 75 | 2017-04-09 | 2017-04-13 |
| mart | 2017-04-13 | 94 | 2017-04-11 | 9999-99-99 |
| neil | 2017-05-10 | 12 | 0000-00-00 | 2017-06-12 |
| neil | 2017-06-12 | 80 | 2017-05-10 | 9999-99-99 |
| tony | 2017-01-02 | 15 | 0000-00-00 | 2017-01-04 |
| tony | 2017-01-04 | 29 | 2017-01-02 | 2017-01-07 |
| tony | 2017-01-07 | 50 | 2017-01-04 | 9999-99-99 |
+-------+-------------+-------+---------------+----------------+
(5)查询顾客每个月第一次的购买时间 和 每个月的最后一次购买时间
select
name,
orderdate,
cost,
first_value(orderdate)over(partition by name order by month(orderdate)),
last_value(orderdate)over(partition by name order by month(orderdate))
from business
+-------+-------------+-------+-----------------------+----------------------+
| name | orderdate | cost | first_value_window_0 | last_value_window_1 |
+-------+-------------+-------+-----------------------+----------------------+
| jack | 2017-01-05 | 46 | 2017-01-05 | 2017-01-01 |
| jack | 2017-01-08 | 55 | 2017-01-05 | 2017-01-01 |
| jack | 2017-01-01 | 10 | 2017-01-05 | 2017-01-01 |
| jack | 2017-02-03 | 23 | 2017-01-05 | 2017-02-03 |
| jack | 2017-04-06 | 42 | 2017-01-05 | 2017-04-06 |
| mart | 2017-04-13 | 94 | 2017-04-13 | 2017-04-08 |
| mart | 2017-04-11 | 75 | 2017-04-13 | 2017-04-08 |
| mart | 2017-04-09 | 68 | 2017-04-13 | 2017-04-08 |
| mart | 2017-04-08 | 62 | 2017-04-13 | 2017-04-08 |
| neil | 2017-05-10 | 12 | 2017-05-10 | 2017-05-10 |
| neil | 2017-06-12 | 80 | 2017-05-10 | 2017-06-12 |
| tony | 2017-01-04 | 29 | 2017-01-04 | 2017-01-07 |
| tony | 2017-01-02 | 15 | 2017-01-04 | 2017-01-07 |
| tony | 2017-01-07 | 50 | 2017-01-04 | 2017-01-07 |
+-------+-------------+-------+-----------------------+----------------------+
(6)查询前20%时间的订单信息
select
name,
orderdate,
cost,
ntile(5)over(order by orderdate)
from business
+-------+-------------+-------+-----------------+
| name | orderdate | cost | ntile_window_0 |
+-------+-------------+-------+-----------------+
| jack | 2017-01-01 | 10 | 1 |
| tony | 2017-01-02 | 15 | 1 |
| tony | 2017-01-04 | 29 | 1 |
| jack | 2017-01-05 | 46 | 2 |
| tony | 2017-01-07 | 50 | 2 |
| jack | 2017-01-08 | 55 | 2 |
| jack | 2017-02-03 | 23 | 3 |
| jack | 2017-04-06 | 42 | 3 |
| mart | 2017-04-08 | 62 | 3 |
| mart | 2017-04-09 | 68 | 4 |
| mart | 2017-04-11 | 75 | 4 |
| mart | 2017-04-13 | 94 | 4 |
| neil | 2017-05-10 | 12 | 5 |
| neil | 2017-06-12 | 80 | 5 |
+-------+-------------+-------+-----------------+
select
t.name,
t.orderdate,
t.cost
from (select
name,
orderdate,
cost,
ntile(5)over(order by orderdate) n
from business
) t
where t.n =1
+---------+--------------+---------+
| t.name | t.orderdate | t.cost |
+---------+--------------+---------+
| jack | 2017-01-01 | 10 |
| tony | 2017-01-02 | 15 |
| tony | 2017-01-04 | 29 |
+---------+--------------+---------+
(7)求每个顾客的购买明细以及上一次购买和下一次购买花费的和
select
name,
orderdate,
cost,
sum(cost)over(partition by name order by orderdate rows between 1 PRECEDING and 1 FOLLOWING)-cost
from business
+-------+-------------+-------+------+
| name | orderdate | cost | _c3 |
+-------+-------------+-------+------+
| jack | 2017-01-01 | 10 | 46 |
| jack | 2017-01-05 | 46 | 65 |
| jack | 2017-01-08 | 55 | 69 |
| jack | 2017-02-03 | 23 | 97 |
| jack | 2017-04-06 | 42 | 23 |
| mart | 2017-04-08 | 62 | 68 |
| mart | 2017-04-09 | 68 | 137 |
| mart | 2017-04-11 | 75 | 162 |
| mart | 2017-04-13 | 94 | 75 |
| neil | 2017-05-10 | 12 | 80 |
| neil | 2017-06-12 | 80 | 12 |
| tony | 2017-01-02 | 15 | 29 |
| tony | 2017-01-04 | 29 | 65 |
| tony | 2017-01-07 | 50 | 29 |
+-------+-------------+-------+------+
RANK函数
RANK() 排序相同时会重复,总数不会变
DENSE_RANK() 排序相同时会重复,总数会减少
ROW_NUMBER() 会根据顺序计算
需求:
name | subject | score |
孙悟空 | 语文 | 87 |
孙悟空 | 数学 | 95 |
孙悟空 | 英语 | 68 |
大海 | 语文 | 94 |
大海 | 数学 | 56 |
大海 | 英语 | 84 |
宋宋 | 语文 | 64 |
宋宋 | 数学 | 86 |
宋宋 | 英语 | 84 |
婷婷 | 语文 | 65 |
婷婷 | 数学 | 85 |
婷婷 | 英语 | 78 |
得到:
name subject score rp drp rmp
孙悟空 数学 95 1 1 1
宋宋 数学 86 2 2 2
婷婷 数学 85 3 3 3
大海 数学 56 4 4 4
宋宋 英语 84 1 1 1
大海 英语 84 1 1 2
婷婷 英语 78 3 2 3
孙悟空 英语 68 4 3 4
大海 语文 94 1 1 1
孙悟空 语文 87 2 2 2
婷婷 语文 65 3 3 3
宋宋 语文 64 4 4 4
步骤:
select
name,
subject,
score,
rank()over(partition by subject order by score desc) r1,
dense_rank()over(partition by subject order by score desc) r2,
row_number()over(partition by subject order by score desc) r3
from score
+-------+----------+--------+-----+-----+-----+
| name | subject | score | r1 | r2 | r3 |
+-------+----------+--------+-----+-----+-----+
| 孙悟空 | 数学 | 95 | 1 | 1 | 1 |
| 宋宋 | 数学 | 86 | 2 | 2 | 2 |
| 婷婷 | 数学 | 85 | 3 | 3 | 3 |
| 大海 | 数学 | 56 | 4 | 4 | 4 |
| 宋宋 | 英语 | 84 | 1 | 1 | 1 |
| 大海 | 英语 | 84 | 1 | 1 | 2 |
| 婷婷 | 英语 | 78 | 3 | 2 | 3 |
| 孙悟空 | 英语 | 68 | 4 | 3 | 4 |
| 大海 | 语文 | 94 | 1 | 1 | 1 |
| 孙悟空 | 语文 | 87 | 2 | 2 | 2 |
| 婷婷 | 语文 | 65 | 3 | 3 | 3 |
| 宋宋 | 语文 | 64 | 4 | 4 | 4 |
+-------+----------+--------+-----+-----+-----+
计算每个人的总分并排序
select
name,
sum(score)over(partition by name) s
from score
group by name, s
+-------+---------------+
| name | sum_window_0 |
+-------+---------------+
| 大海 | 234 |
| 大海 | 234 |
| 大海 | 234 |
| 婷婷 | 228 |
| 婷婷 | 228 |
| 婷婷 | 228 |
| 孙悟空 | 250 |
| 孙悟空 | 250 |
| 孙悟空 | 250 |
| 宋宋 | 234 |
| 宋宋 | 234 |
| 宋宋 | 234 |
+-------+---------------+
//注意:Hive不允许直接访问非group by字段
select
t.name,
t.ss
from(select
name,
sum(score)over(partition by name) ss
from score
) t
group by t.name,t.ss
+---------+-------+
| t.name | t.ss |
+---------+-------+
| 大海 | 234 |
| 婷婷 | 228 |
| 孙悟空 | 250 |
| 宋宋 | 234 |
+---------+-------+
select
d.t1,
d.t2,
rank()over(order by d.t2 desc rows between UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING)
from (select
t.name t1,
t.ss t2
from(select
name,
sum(score)over(partition by name) ss
from score
) t
group by t.name,t.ss) d
+-------+-------+----------------+
| d.t1 | d.t2 | rank_window_0 |
+-------+-------+----------------+
| 孙悟空 | 250 | 1 |
| 宋宋 | 234 | 2 |
| 大海 | 234 | 2 |
| 婷婷 | 228 | 4 |
+-------+-------+----------------+
6.自定义函数以及举例
(1)UDF(User-Defined-Function)
一进一出
(2)UDAF(User-Defined Aggregation Function)
用户自定义聚合函数,多进一出
类似于:count/max/min
(3)UDTF(User-Defined Table-Generating Functions)
用户自定义表生成函数,一进多出
如lateral view explode()
举例:
自定义一个UDF实现计算给定基本数据类型的长度
1.导入依赖
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
2.编写代码
package com.hpu;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
/**
* @author LS
* @date 2021/12/24 18:21
* @description
*/
public class hive_udf extends GenericUDF {
//判断传进来的参数的类型和长度 约定返回的数据类型
@Override
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
if (arguments.length != 1){
throw new UDFArgumentLengthException("give one please");
}
if (!arguments[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE)){
throw new UDFArgumentTypeException(1, "i need primitive type arg");
}
return PrimitiveObjectInspectorFactory.javaIntObjectInspector;
}
//解决具体逻辑的
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
Object o = arguments[0].get();
if(o==null){
return 0;
}
return o.toString().length();
}
//用于获取解释的字符串
@Override
public String getDisplayString(String[] strings) {
return "";
}
}
3.在hive端步骤
1.创建临时函数
(1)打成jar包上传到服务器/opt/module/hive/datas/udf.jar
(2)将jar包添加到hive的classpath,临时生效
add jar /opt/module/hive/datas/udf.jar;
(3)创建临时函数与开发好的java class关联
create temporary function my_len as "com.hpu.hive.hive_udf";
(4)即可在hql中使用自定义的临时函数
select my_len(aaaa);
(5)删除临时函数
drop temporary function my_len;
注意:临时函数只在当前会话内有效
2.创建永久函数
(1)创建永久函数
create function my_len2 as "com.hpu.hive.hive_udf" using jar "hdfs://hadoop102:8020/udf/udf.jar";
(2)即可在hql中使用自定义的永久函数
select my_len(aaaa);
(3)删除永久函数
drop function my_len2;
注意:永久函数跟会话没有关系,创建函数的会话断了以后,其他会话也可以使用。
永久函数创建的时候,在函数名之前需要自己加上库名,如果不指定库名的话,会默认把当前库的库名给加上。
永久函数使用的时候,需要在指定的库里面操作,或者在其他库里面使用的话加上 库名.函数名