目录

  • 1、Hive函数分类
  • 1.1、从输入输出角度分类
  • 1.2、从实现方式分类
  • 2、内置函数
  • 2.1、字符函数
  • (1)concat()
  • (2)concat_ws()
  • (3)instr(string,substr)
  • (4)length(string)
  • (5)locate(substr,str,pos)
  • (6)lower(string) /upper(string)
  • (7)regexp_replace(x,y,z)
  • (8)split(string,x)
  • (9)substr(string,x,y)/substring(string,x,y)
  • (10)trim(string)
  • (11)str_to_map(text[, delimiter1, delimiter2])
  • 2.2、类型转换函数
  • (1)cast(expr as )
  • (2)binary(string)
  • 2.3、数学函数
  • (1)round(x,y)
  • (2)ceil(x)
  • (3)floor(x)
  • (4)rand(x)
  • (5)power(x,n)
  • (6)abs(x)
  • 2.4、日期函数
  • (1)from_unixtime(unixtime,"yyyy-MM-dd HH:mm:ss")
  • (2)unix_timestamp("yyyy-MM-dd HH:mm:ss")
  • (3)to_date("yyyy-MM-dd HH:mm:ss")
  • (4)year("yyyy-MM-dd HH:mm:ss")
  • (5)month("yyyy-MM-dd HH:mm:ss")
  • (6)day("yyyy-MM-dd HH:mm:ss")
  • (7)hour("yyyy-MM-dd HH:mm:ss")
  • (8)minute("yyyy-MM-dd HH:mm:ss")
  • (9)second("yyyy-MM-dd HH:mm:ss")
  • (10)weekofyear("yyyy-MM-dd HH:mm:ss")
  • (11)datediff(enddate,startdate)
  • (12)date_add(startdate,days)
  • (13)date_sub(startdate,days)
  • (14)current_date()
  • (15)current_timestamp
  • (16)date_format("yyyy-MM-dd HH:mm:ss","MM-dd HH:mm:ss")
  • 2.5、集合函数
  • (1)size(map)
  • (2)size(array)
  • (3)map_keys(map)
  • (4)map_values(map)
  • (5)array_contains(array, value)
  • (6)sort_array(array)
  • 2.6、条件函数
  • (1)if(x, y, z)
  • (2)case when
  • (3)isnull
  • (4)isnotnull
  • (5)nvl(x,y)
  • (6)coalesce
  • 2.7、聚合函数
  • 2.8、表生成函数
  • (1)explode(array)
  • (2)explode(map)
  • (3)posexplode(array)
  • (4)stack(int n, v_1, v_2, ..., v_k)
  • 3、自定义函数
  • 3.1、Hive UDF函数
  • (1)开发流程
  • (2)UDF的实现
  • 4、窗口函数


1、Hive函数分类

1.1、从输入输出角度分类

标准函数:一行数据中的一列或多列为输入,结果为单一值
聚合函数:多行的零列到多列为输入,结果为单一值
表生成函数:零个或多个输入,结果为多列或多行

1.2、从实现方式分类

内置函数

  • 字符函数
  • 类型转换函数
  • 数学函数
  • 日期函数
  • 集合函数
  • 条件函数
  • 聚合函数
  • 表生成函数

自定义函数

  • UDF:自定义标准函数
  • UDAF:自定义聚合函数
  • UDTF:自定义表生成函数

2、内置函数

2.1、字符函数

concat

concat_ws

instr

length

locate

regexp_replace

lower

upper

split

substr

trim

str_to_map

(1)concat()

用于拼接字符串,每个字符串之间都需要添加指定分隔符
返回值类型:string

示例:
拼接表中的 name 和 dept_num 字段,并添加一个 name 列

select concat("name",":",name,"--",dept_num) as con from employee_contract;

运行结果如下:

+---------------------+--+
|         con         |
+---------------------+--+
| name:Michael--1000  |
| name:Will--1000     |
| name:Wendy--1000    |
| name:Steven--1000   |
| name:Lucy--1000     |
| name:Lily--1001     |
| name:Jess--1001     |
| name:Mike--1001     |
| name:Wei--1002      |
| name:Yun--1002      |
| name:Richard--1002  |
+---------------------+--+

(2)concat_ws()

拼接字符串,第一个参数为分隔符,其后都为需要拼接的字符串
返回值类型:string

示例:
多行转一行,查找出每个部门的员工姓名

select dept_num,
concat_ws(",",collect_list(name)) as con_name
from employee_contract
group by dept_num;

运行结果如下:

+-----------+---------------------------------+--+
| dept_num  |            con_name             |
+-----------+---------------------------------+--+
| 1000      | Michael,Will,Wendy,Steven,Lucy  |
| 1001      | Lily,Jess,Mike                  |
| 1002      | Wei,Yun,Richard                 |
+-----------+---------------------------------+--+

(3)instr(string,substr)

返回子字符串 substr 在 string 中的位置,若不存在则返回 0
返回值类型:int

示例:
判断一个字符串是否在这一列中存在,查找 employee 表中 name 字段中含有 i 的信息

select * from employee where instr(name,"i")>0;

运行结果如下:

+----------------+-------------------------+--------------------------+------------------------+---------------------------------------+--+
| employee.name  |   employee.work_place   |     employee.sex_age     | employee.skills_score  |         employee.depart_title         |
+----------------+-------------------------+--------------------------+------------------------+---------------------------------------+--+
| Michael        | ["Montreal","Toronto"]  | {"sex":"Male","age":30}  | {"DB":80}              | {"Product":["Developer","Lead"]}      |
| Will           | ["Montreal"]            | {"sex":"Male","age":35}  | {"Perl":85}            | {"Product":["Lead"],"Test":["Lead"]}  |
+----------------+-------------------------+--------------------------+------------------------+---------------------------------------+--+

(4)length(string)

返回字符串长度
返回值类型:int

示例:
返回字符串长度

select length("abcdefg");

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 7    |
+------+--+

(5)locate(substr,str,pos)

查找字符串 str 中的 pos 位置后字符串 substr 第一次出现的位置
返回值类型:int

示例:
查找abc:hello word a b c中第四个字符字以后a的位置

select locate("a","abc:hello word a b c",4);

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 16   |
+------+--+

(6)lower(string) /upper(string)

将字符串中的所有字母转换成小写/大写字母
返回值类型:string

示例:

select upper("Hello word");
select lower("Hello WORD");

运行结果如下:

+-------------+--+
|     _c0     |
+-------------+--+
| HELLO WORD  |
+-------------+--+

+-------------+--+
|     _c0     |
+-------------+--+
| hello word  |
+-------------+--+

(7)regexp_replace(x,y,z)

替换字符串中的指定字段
第一个参数 x 为字符串
第二种参数 y 为需要替换的字符
第三个参数 z 为替换成的字符
返回值类型:string

示例:
将字符串中的一个或多个空格替换为

select regexp_replace("hello word I Love you","\\s",",");

运行结果如下:

+------------------------+--+
|          _c0           |
+------------------------+--+
| hello,word,I,Love,you  |
+------------------------+--+

(8)split(string,x)

以指定的 x 为分隔符切割字符串
返回值类型:array

示例:
按逗号切割自定义字符串

select split("hello word,I Love you,I'am a student",",");

运行结果如下:

+-----------------------------------------------+--+
|                      _c0                      |
+-----------------------------------------------+--+
| ["hello word","I Love you","I'am a student"]  |
+-----------------------------------------------+--+

(9)substr(string,x,y)/substring(string,x,y)

截取字符串
从第 x 位开始,截取长度为 y 的字符串
返回值类型:string

示例:

select substr("2020-12-14 10:17:30",0,7);
select substring("2020-12-14 10:17:30",0,7);

运行结果如下:

+----------+--+
|   _c0    |
+----------+--+
| 2020-12  |
+----------+--+

(10)trim(string)

去掉字符串前后的空格
返回值类型:string

示例:

select trim("    abcds   ");

运行结果如下:

+--------+--+
|  _c0   |
+--------+--+
| abcds  |
+--------+--+

(11)str_to_map(text[, delimiter1, delimiter2])

将字符串str按照指定分隔符转换成Map
返回值类型:map

示例:

select str_to_map("name:ZS,age:24",",");

运行结果如下:

+---------------------------+--+
|            _c0            |
+---------------------------+--+
| {"name":"ZS","age":"24"}  |
+---------------------------+--+

2.2、类型转换函数

(1)cast(expr as )

将 expr 转换成 type 类型
返回值类型:type

示例:

select cast("1.02" as int);

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 1    |
+------+--+

(2)binary(string)

将输入的值转换成二进制
返回值类型:binary

示例:

select binary('8');

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 8    |
+------+--+

2.3、数学函数

round

ceil

floor

rand

power

abs

(1)round(x,y)

对 x 进行四舍五入取整,保留 y 位小数,不写 y 表示不保留小数
返回值类型:double/binary

示例:

select round(5.55);

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 6.0  |
+------+--+

(2)ceil(x)

小数向上取整
返回值类型:bigint

示例:

select ceil(1.2);

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 2    |
+------+--+

(3)floor(x)

小数向下取整
返回值类型:bigint

示例:

select floor(5.55);

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 5    |
+------+--+

(4)rand(x)

返回一个 0 到 1 的 double 型随机数
x是随机因子,指定随机因子x,则会等到一个稳定的随机数序列
返回值类型:double

示例1:

select rand();

运行结果如下:

+---------------------+--+
|         _c0         |
+---------------------+--+
| 0.8360579048475161  |
+---------------------+--+

示例2:
求一个 1 到 10 的随机数

select round(rand()*10);

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 5.0  |
+------+--+

(5)power(x,n)

求指定 x 的 n 次方
返回值类型:double

示例:

select power(10,3);

运行结果如下:

+---------+--+
|   _c0   |
+---------+--+
| 1000.0  |
+---------+--+

(6)abs(x)

求 x 的绝对值
返回值类型:double

示例:

select abs(-9.250);
select abs(9.250);

运行结果如下:

+-------+--+
|  _c0  |
+-------+--+
| 9.25  |
+-------+--+

2.4、日期函数

from_unixtime

unix_timestamp

to_date

year

month

day

hour

minute

second

weekofyear

datediff

date_add

date_sub

current_date

current_timestamp

date_format

(1)from_unixtime(unixtime,“yyyy-MM-dd HH:mm:ss”)

将时间戳转换成format格式,时间格式可选,不选则为默认时间格式
返回值类型:string

示例:
时间戳转化为时间,使用指定的时间格式

select from_unixtime(1607914665,"yyyy-MM-dd");

运行结果如下:

+-------------+--+
|     _c0     |
+-------------+--+
| 2020-12-14  |
+-------------+--+

(2)unix_timestamp(“yyyy-MM-dd HH:mm:ss”)

将格式为"yyyy-MM-dd HH:mm:ss"的时间字符串转换成时间戳
无参数时输系统当前时间的时间戳
返回值类型:int/bigint

示例:

select unix_timestamp();

运行结果如下:

+-------------+--+
|     _c0     |
+-------------+--+
| 1607931757  |
+-------------+--+

(3)to_date(“yyyy-MM-dd HH:mm:ss”)

返回时间字符串的日期部分
返回值类型:string

示例:

select to_date("2020-12-14 11:29:59");

运行结果如下:

+-------------+--+
|     _c0     |
+-------------+--+
| 2020-12-14  |
+-------------+--+

(4)year(“yyyy-MM-dd HH:mm:ss”)

返回时间字符串中的年份
返回值类型:int

示例:

select year("2020-12-14 11:29:59");

运行结果如下:

+-------+--+
|  _c0  |
+-------+--+
| 2020  |
+-------+--+

(5)month(“yyyy-MM-dd HH:mm:ss”)

返回时间字符串中的月份
返回值类型:int

示例:

select month("2020-12-14 11:29:59");

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 12   |
+------+--+

(6)day(“yyyy-MM-dd HH:mm:ss”)

返回时间字符串中的日期(号数)
返回值类型:int

示例:

select day("2020-12-14 11:29:59");

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 14   |
+------+--+

(7)hour(“yyyy-MM-dd HH:mm:ss”)

返回时间字符串中的小时数
返回值类型:int

示例:

select hour("2020-12-14 11:29:59");

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 11   |
+------+--+

(8)minute(“yyyy-MM-dd HH:mm:ss”)

返回时间字符串中的分钟数
返回值类型:int

示例:

select minute("2020-12-14 11:29:59");

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 29   |
+------+--+

(9)second(“yyyy-MM-dd HH:mm:ss”)

返回时间字符串中的秒数
返回值类型:int

示例:

select second("2020-12-14 11:29:59");

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 59   |
+------+--+

(10)weekofyear(“yyyy-MM-dd HH:mm:ss”)

返回时间在当年是第几周
返回值类型:int

示例:

select weekofyear("2020-12-14 11:29:59");

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 51   |
+------+--+

(11)datediff(enddate,startdate)

计算开始时间到结束时间相差的天数
返回值类型:int

示例:

select datediff("2020-12-14","2020-12-01");

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 13   |
+------+--+

(12)date_add(startdate,days)

从开始时间 startdate 加上 days 后的日期
返回值类型:string

示例:

select date_add("2020-12-14 11:45:58",3);

运行结果如下:

+-------------+--+
|     _c0     |
+-------------+--+
| 2020-12-17  |
+-------------+--+

(13)date_sub(startdate,days)

从开始时间 startdate 减去 days 后的日期
返回值类型:string

示例:

select date_sub("2020-12-14 11:45:58",3);

运行结果如下:

+-------------+--+
|     _c0     |
+-------------+--+
| 2020-12-11  |
+-------------+--+

(14)current_date()

返回当前时间的日期
返回值类型:date

示例:

select current_date();

运行结果如下:

+-------------+--+
|     _c0     |
+-------------+--+
| 2020-12-14  |
+-------------+--+

(15)current_timestamp

返回当前时间,精确到毫秒
返回值类型:timestamp

示例:

select current_timestamp();

运行结果如下:

+--------------------------+--+
|           _c0            |
+--------------------------+--+
| 2020-12-14 11:44:58.431  |
+--------------------------+--+

(16)date_format(“yyyy-MM-dd HH:mm:ss”,“MM-dd HH:mm:ss”)

按指定格式返回时间date
返回值类型:string

示例:

select date_format("2020-12-14 11:45:58","MM-dd HH:mm:ss");

运行结果如下:

+-----------------+--+
|       _c0       |
+-----------------+--+
| 12-14 11:45:58  |
+-----------------+--+

2.5、集合函数

size(Map<K,V>)

size(Array)

map_keys(Map<K,V>)

map_values(Map<K,V>)

array_contains(Array, value)

sort_array(Array)

(1)size(map)

返回 map 中键值对个数
返回值类型:int

示例:

select size((map("ZS",25,"LS",22,"WW",36)));

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 3    |
+------+--+

(2)size(array)

返回数组的元素数量
返回值类型:int

示例:

select size(array(1,2,3,4,5));

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 5    |
+------+--+

(3)map_keys(map)

返回 map 中的所有 key
返回值类型:array<k>

示例:

select map_keys((map("ZS",25,"LS",22,"WW",36)));

运行结果如下:

+-------------------+--+
|        _c0        |
+-------------------+--+
| ["ZS","LS","WW"]  |
+-------------------+--+

(4)map_values(map)

返回 map 中的所有 values
返回值类型:array<V>

示例:

select map_values((map("ZS",25,"LS",22,"WW",36)));

运行结果如下:

+-------------+--+
|     _c0     |
+-------------+--+
| [25,22,36]  |
+-------------+--+

(5)array_contains(array, value)

该数组 Array 中包含 value 返回 true,否则返回 false
返回值类型:boolean

示例:

select array_contains(array(1,2,34,5),2);

运行结果如下:

+-------+--+
|  _c0  |
+-------+--+
| true  |
+-------+--+

(6)sort_array(array)

对数组进行正序排序
返回值类型:array

示例:

select sort_array(array(1,2,5,4,2,3,8,9,6,7,2,1,0));

运行结果如下:

+------------------------------+--+
|             _c0              |
+------------------------------+--+
| [0,1,1,2,2,2,3,4,5,6,7,8,9]  |
+------------------------------+--+

2.6、条件函数

函数

说明

if(x, y, z)

如果条件 x 为结果 true 就返回 x,否则返回 y

case when

类似于 java 中的 switch

isnull(x)

如果 x 为 null 就返回 true,否则返回 false

isnotnull (x)

如果 x 为非 null 就返回 true,否则返回 false

nvl(x,y)

将 x 替换为 y

coalesce

返回第一非null的值,如果全部都为 null 就返回 null

(1)if(x, y, z)

条件判断输出
效果与三元表达式相同
第一个参数结果为 true,则返回第二个参数,反之则返回第三参数

示例:
工资分类
示例:

select name,
if(salary>5000,"高收入人群","低收入人群") as c
from employee_contract;

运行结果如下:

+----------+--------+--+
|   name   |   c    |
+----------+--------+--+
| Michael  | 低收入人群  |
| Will     | 低收入人群  |
| Wendy    | 低收入人群  |
| Steven   | 高收入人群  |
| Lucy     | 高收入人群  |
| Lily     | 低收入人群  |
| Jess     | 高收入人群  |
| Mike     | 高收入人群  |
| Wei      | 高收入人群  |
| Yun      | 高收入人群  |
| Richard  | 高收入人群  |
+----------+--------+--+

(2)case when

类似于 java 中的 switch 语句
用于多分支条件判断

示例:
– 薪资分级
– 薪资小于4000,低收入人群
– 薪资大于4000,小于等于6000,中收入人群
– 薪资大于6000,高收入人群

select name,salary,
(case when salary<=4000 then "低收入人群"
when salary>4000 and salary<6000 then "中收入人群"
else "高收入人群" end) as fenlei
from employee_contract;

运行结果如下:

+----------+---------+---------+--+
|   name   | salary  | fenlei  |
+----------+---------+---------+--+
| Michael  | 5000    | 中收入人群   |
| Will     | 4000    | 低收入人群   |
| Wendy    | 4000    | 低收入人群   |
| Steven   | 6400    | 高收入人群   |
| Lucy     | 5500    | 中收入人群   |
| Lily     | 5000    | 中收入人群   |
| Jess     | 6000    | 高收入人群   |
| Mike     | 6400    | 高收入人群   |
| Wei      | 7000    | 高收入人群   |
| Yun      | 5500    | 中收入人群   |
| Richard  | 8000    | 高收入人群   |
+----------+---------+---------+--+

(3)isnull

判断字符串是否为空
为空输出 true,否则输出 false
返回值类型:boolean

示例:

select isnull(null);
select isnull("null");	-- 注意:这表示一个null字符串,不为空,返回false

运行结果如下:

+-------+--+
|  _c0  |
+-------+--+
| true  |
+-------+--+

(4)isnotnull

与 isnull 相反
判断字符串是否不为空
不为空输出 true,否则输出 false
返回值类型:boolean

示例:

select isnotnull("null");

运行结果如下:

+-------+--+
|  _c0  |
+-------+--+
| true  |
+-------+--+

(5)nvl(x,y)

对 x 做处理,替换为y

示例:

select nvl(null,0)

运行结果如下:

+------+--+
| _c0  |
+------+--+
| 0    |
+------+--+

(6)coalesce

返回第一个不为空的值
若全部为空,则返回 null

示例:

select coalesce(null,null,"hello","word");

运行结果如下:

+--------+--+
|  _c0   |
+--------+--+
| hello  |
+--------+--+

2.7、聚合函数

函数

说明

count

计算结果行数

sum

求和

max

求最大值

min

求最小值

avg

求平均值

示例:
– 按部门分组
– 求员工人数、每个部门最高薪资、最低薪资、薪资总和以及平均薪资

select dept_num,
count(name) as num,
max(salary) as max_salary,
min(salary) as min_salary,
sum(salary) as sum_salary,
avg(salary) as avg_salary
from employee_contract
group by dept_num;

运行结果如下:

+-----------+------+-------------+-------------+-------------+--------------------+--+
| dept_num  | num  | max_salary  | min_salary  | sum_salary  |     avg_salary     |
+-----------+------+-------------+-------------+-------------+--------------------+--+
| 1000      | 5    | 6400        | 4000        | 24900       | 4980.0             |
| 1001      | 3    | 6400        | 5000        | 17400       | 5800.0             |
| 1002      | 3    | 8000        | 5500        | 20500       | 6833.333333333333  |
+-----------+------+-------------+-------------+-------------+--------------------+--+

2.8、表生成函数

函数

说明

explode(array)

对于 array 中的每个元素生成一行且包含该元素

explode(map)

每行对应每个map键值对,其中一个字段是map的键,另一个字段是map的值

posexplode(array)

与explode类似,不同的是还返回各元素在数组中的位置

json_tuple(jsonStr, k1, k2, …)

从一个 json 字符串中获取多个键并作为一个元组返回,与get_json_object不同的是此函数能一次获取多个键值

(1)explode(array)

对于 array 中的每个元素生成一行且包含该元素

示例:

select explode(array(1,2,3,4,5));

运行结果如下:

+------+--+
| col  |
+------+--+
| 1    |
| 2    |
| 3    |
| 4    |
| 5    |
+------+--+

(2)explode(map)

每行对应每个 map 键值对,其中一个字段是 map 的键,另一个字段是 map 的值

示例:

select explode(array(1,2,3,4,5));

运行结果如下:

+------+--+
| col  |
+------+--+
| 1    |
| 2    |
| 3    |
| 4    |
| 5    |
+------+--+

(3)posexplode(array)

与explode类似,不同的是还返回各元素在数组中的位置

示例:

select posexplode(array(4,9,8,7,6));

运行结果如下:

+------+------+--+
| pos  | val  |
+------+------+--+
| 0    | 4    |
| 1    | 9    |
| 2    | 8    |
| 3    | 7    |
| 4    | 6    |
+------+------+--+

(4)stack(int n, v_1, v_2, …, v_k)

把k列转换成 n 行,每行有 k/n 个字段,其中 n 必须是常数
注意:k 必须是 n 的倍数,k/n 为列数

示例:

select stack(1,"ZS","LS","WW")

运行结果如下:

+-------+-------+-------+--+
| col0  | col1  | col2  |
+-------+-------+-------+--+
| ZS    | LS    | WW    |
+-------+-------+-------+--+

3、自定义函数

3.1、Hive UDF函数

(1)开发流程

继承UDF类或GenericUDF类
重写evaluate()方法并实现函数逻辑
编译打包为jar文件
复制到正确的HDFS路径
使用jar创建临时/永久函数
调用函数

(2)UDF的实现

  • 创建Maven项目
  • 创建类继承UDF类,重写 evaluate() 方法,编写函数功能
public class MyUDF extends UDF {
    //重写evaluate方法
    public Text evaluate(Text s){
        //把字符串转换成小写
        return new Text(s.toString().toLowerCase());
    }
}
  • 打 jar 包,并上传到 Linux
  • 添加 jar 包到 Hive
add jar /opt//hiveUDF.jar;
  • 创建临时自定义函数
  • 临时函数仅当前会话有效,退出后自动删除
  • 不使用 temporary 关键字则创建永久 UDF 函数
  • 永久 UDF 仅在创建函数时所在的库有用
create temporary function hiveudf as "cn.kgc.udf.MyUDF";
  • 使用临时 UDF 函数
select hiveudf("hello WORD");

结果如下:

+-------------+--+
|     _c0     |
+-------------+--+
| hello word  |
+-------------+--+

4、窗口函数

常用窗口函数请查看: Hive窗口函数.