前言
Hive作为一款构建于Hadoop之上的数据仓库工具,拥有强大的数据处理与分析能力。它能够将结构化的数据文件巧妙映射为数据库表,同时提供简洁易用的SQL查询功能,能把SQL语句无缝转换为MapReduce任务来执行。Hive的显著优势在于其较低的学习门槛,用户仅需运用类SQL语句,就能迅速实现简单的MapReduce统计操作,而无需耗费精力开发专门的MapReduce应用程序,这一特性使其在数据仓库的统计分析场景中表现卓越,成为众多数据分析师和开发者的得力助手。
在功能设计上,Hive充分考虑到用户的使用便捷性,将常用的逻辑封装成函数供用户调用,这与Java语言中的函数概念相似。这种封装机制的好处显而易见,它极大地避免了用户重复编写复杂逻辑的繁琐过程,用户只需了解函数的名称和功能,便可直接调用,有效提高了工作效率。
Hive中的函数种类丰富,大致可划分为五类,分别是单行函数、聚合函数、炸裂函数、窗口函数以及自定义函数。今天,我们将着重介绍除自定义函数之外的其他四类函数,并结合具体案例展示它们的使用方法,帮助大家更好地理解和运用Hive函数进行数据处理与分析。
一、单行函数
单行函数的特点是一进一出,大致可以分为数学函数,日期函数,字符串函数,流程控制函数,集合函数。
1. 数学函数
运算符 | 描述 |
---|---|
A+B | A和B 相加 |
A-B | A减去B |
A*B | A和B 相乘 |
A/B | A除以B |
A%B | A对B取余 |
A&B | A和B按位取与 |
A|B | A和B按位取或 |
A^B | A和B按位取异或 |
~A | A按位取反 |
数学函数针对于数值形式的计算,返回值均为数值类型。示例:
select 1 + 1; 2select 1 - 1; 0select 2 * 2; 4select 3 / 2; 1.5select 5 % 2; 1select 1 & 2; 0select 1 | 2; 3select 1 ^ 2; 3select ~1; -2
2. 日期函数
运算符 | 描述 |
---|---|
unix_timestamp | 返回当前或指定时间的时间戳 |
from_unixtime | 将时间戳转换为指定格式的时间 |
year | 返回日期当中的年 |
month | 返回日期当中的月 |
day | 返回日期当中的天 |
datediff | 两个日期相差的天数 |
date_add | 日期加上天数 |
date_sub | 日期减去天数 |
date_format | 将日期转换为指定格式 |
① unix_timestamp(string time):返回值为bigint类型。
select unix_timestamp('2023-04-06 15:31:26');
1680795086
② from_unixtime(bigint time [,string format]):返回值为 string
类型。
select from_unixtime(1680795086);
2023-04-06 15:31:26
③ year(string time):返回值为int类型。
select year('2023-04-06 15:31:26');
2023
④ month(string time):返回值为int类型。
select month('2023-04-06 15:31:26');
4
⑤ day(string time):返回值为int类型。
select day('2023-04-06 15:31:26');
6
⑥ datediff(string time,string time):返回值类型为int类型。
select datediff('2023-04-07','2023-04-06');
1
⑦ date_add(string date,int day):返回值为date类型。
select date_add('2023-04-06',1);
2023-04-07
⑧ date_sub(string date,int day):返回值为date类型。
select date_sub('2023-04-06',1);
2023-04-05
⑨ date_format(string date,string format):返回值为string类型。
select date_format('2023-04-06 15:45:25','yyyy-MM-dd');
2023-04-06
3. 字符串函数
运算符 | 描述 |
---|---|
upper | 转大写 |
lower | 转小写 |
length | 获取字符串长度 |
trim | 去除字符串两边的空格 |
substring | 截取字符串 |
replace | 替换 |
split | 将字符串切割 |
concat_ws | 以指定分隔符拼接字符串 |
get_json_object | 获取json字符串的内容 |
① upper(string str)
:返回值为string类型。
select upper('abc');
ABC
② lower(string str)
:返回值为string类型。
select lower('ABC');
abc
③ length(string str)
:返回值为int类型。
select length('atguigu');
7
④ trim(string str)
:返回值为string类型。
select trim(' abc ');
abc
⑤ substring(string str,int start[,int end])
:返回值为string类型。
select substring('atguigu',2,5);
tguig
⑥ replace(string str,string bef,string las)
:返回值为string类型。
select replace('atguigu','a','b');
btguigu
⑦ split(string str,string par)
:返回值为array类型。
select split('atguigu','g');
["at","ui","u"]
⑧ concat\_ws(string spl,string s1,string s2,...)
:返回值为string类型。
select concat_ws('-','a','b','c');
a-b-c
⑨ get_json_object(string json,string path)
:返回值为string类型。
select get_json_object('{"data1":1,"data2":2}','$.data2');
2
3. 流程控制函数
运算符 | 描述 |
---|---|
case when | 条件判断 |
if | 类似于三元运算符 |
示例:
select case 100 when 50 then 'tom' when 100 then 'mary' else 'tim' end;maryselect if(2>3,2,3);
3
3. 集合函数
运算符 | 描述 |
---|---|
size | 集合中元素的个数 |
map_keys | 返回map中的key |
map_values | 返回map中的value |
array_contains | 判断数组中是否包含某个元素 |
sort_array | 将数组中元素排序 |
① size(array/map m)
:返回值为int类型。
select size(array('a','b','c'));3
② map_keys(map m)
:返回值为array类型。
select map_keys(test) from test;
[1,2,3]
test字段值为{"1":"a","2":"b","3","c"}
③ map_values(map m)
:返回值为array类型。
select map_values(test) from test;
["a","b","c"]
④ array_contains(array arr,string str)
:返回值为boolean类型。
select array_contains(array('1','2','3'),'4');
false
⑤ sort_array(array arr)
:返回值为array类型。
select sort_array(array(4,2,3,1));
[1,2,3,4]
二\聚合函数
聚合函数对一组数据进行计算,并返回单个值。
测试数据test表:
id | name | score |
---|---|---|
1 | atguigu1 | 60 |
2 | atguigu2 | 50 |
3 | atguigu3 | 80 |
4 | atguigu3 | 70 |
1. 普通聚合
运算符 | 描述 |
---|---|
count | 求行数,对NULL不计入 |
sum | 累计求和 |
max | 求最大值 |
min | 求最小值 |
avg | 求平均数 |
示例:
select count(*) from test;4select sum(score) from test;
260
select max(score) from test;
80
select min(score) from test;
50
select avg(score) from test;
65
2. 高级聚合
运算符 | 描述 |
---|---|
collect_list | 收集并形成list集合,结果不去重 |
collect_set | 收集并形成set集合,结果去重 |
示例:
select collect_list(name) from test;
["atguigu1","atguigu2","atguigu3","atguigu3"]
elect collect_set(name) from test;
["atguigu1","atguigu2","atguigu3"]
3. 分组
Group By语句通常会和聚合函数一起使用,按照一个或者多个列队结果进行分组,然后对每个组执行聚合操作,同时可以使用having进行过滤。
示例:
select id,avg(score) avg_sfrom testgroup by idhaving avg_s > 60;
三\炸裂函数
Hive处理的数据字段是可再分的,不满足原子性,即DDL可以定义一个字段类型为数组,因此才有了explode()函数,用于给这个字段展开降维,把指定的数组字段拆分降维展开为多行。类似于UDTF函数,作用于单/多个数据行,并且产生多个数据行,以一个表作为输出。
1. explode 将数组或者map展开
例:
select explode(array('a','b','c','d'));
结果:
a b c d
2. json_tuple
取出json字符串中的属性值
例:
select json_tuple('{"name":"王二狗","sex":"男","age":"25"}','name','sex','age');
结果:
王二狗 男 25
3. lateral view
侧写
炸裂函数和聚合函数有所不同,它不支持与普通列直接一起查询,所以通常会配合侧写(lateral view)进行查询操作 。
用法:lateral view udtf(expression) tableAlias AS columnAlias
解释:lateral view
主要用于和split
、explode
等用户自定义表生成函数(UDTF)协同工作。其核心作用是将一行数据拆分成多行数据,并且在拆分的基础上,还能对拆分后的数据执行聚合操作。具体过程为,lateral view
首先针对原始表中的每一行数据调用UDTF,UDTF会将这一行数据拆分成一行或者多行,然后lateral view
再将这些拆分后的结果进行组合,最终生成一个支持别名表的虚拟表。举例如下:
select movie, category_namefrom movie_infolateral viewexplode(split(category,",")) movie_info_tmp AS category_name;
四、窗口函数
窗口函数,也可以叫开窗函数,其从本质来看是将Hive 中一些复杂的查询封装成了窗口的形式,进行数据统计时使用并且操 作十分方便,窗口函数为统计时使用的聚合函数指定一个聚合的范围。
1. 语法
基本语法:函数 + over( [partition by ...] [order by ...] [窗口子句] )
over表示开窗,默认窗口大小会包含所有数据。
partition by表示根据字段再划分一个细窗口,相同字段进入同一个细窗口里面,每个窗口之间相互独立,窗口子句对于每个细窗口独立生效。
order by表示窗口内按什么排序,如果只有over表示直接最大窗口排序;如果有partition by每个细窗口单独排序。
窗口子句,可以进一步限定范围
(rows | range) between (unbounded | [num]) preceding and ([num] preceding | current row | (unbounded | [num]) following (rows | range) between current row and (current row | (unbounded | [num]) following)(rows | range) between [num] following and (unbounded | [num]) following
示例:
rows between unbounded preceding and unbounded following 行的范围为上无边界到下无边界(第一行到最后一行)。
注:窗口函数是一行一行执行的。
**2. 使用
① 窗口函数
lag(col, n, default_val)
:用于获取当前行往前第n
行的数据。若往前第n
行不存在数据,则返回default_val
。lead(col, n, default_val)
:用于获取当前行往后第n
行的数据。若往后第n
行不存在数据,则返回default_val
。first_value(col, true/false)
:返回当前窗口内的第一个值。当第二个参数为true
时,会跳过空值来获取第一个非空值。last_value(col, true/false)
:返回当前窗口内的最后一个值。当第二个参数为true
时,会跳过空值来获取最后一个非空值。
② 聚合函数
max
:用于计算一组数据中的最大值。min
:用于计算一组数据中的最小值。sum
:对一组数据进行求和操作。avg
:计算一组数据的平均值。count
:统计数据的数量。
③ 排名分析函数
rank
:进行排名时,若存在相同排名,名次会重复,且后续排名会按照重复后的总数依次顺延,即总数不会减少。dense_rank
:排名相同时名次会重复,但后续排名会连续递增,总数会减少。row_number
:为每一行数据分配一个唯一的行号。ntile
:将数据进行分组,并为每组分配一个组号。
注意事项
- 窗口函数的执行顺序是在
GROUP BY
子句之后。这意味着先对数据进行分组操作,然后再应用窗口函数进行进一步的计算和分析。 - 有时候,添加或不添加窗口子句得到的结果是相同的。这是因为窗口子句存在默认值。当存在
ORDER BY
子句但缺少窗口子句时,窗口范围是从无上限边界到当前行;当ORDER BY
子句和窗口子句都缺失时,窗口范围是从无上限边界到无下限边界。 - 并非所有函数都需要指定窗口子句。像
rank
、dense_rank
、ntile
、row_number
、lag
、lead
这些函数是不支持使用窗口子句的。 - 在使用排名分析函数时,通常不需要传入额外的参数,这些函数会自动对排好序的数据进行编号。
4. 使用示例
例如,表table,字段为id,sub,score,需求出表每门学科的成绩排名。
select id, sub, score, rank() over(distribute by sub sort by score desc) rankfrom table;
五、总结**
本文给大家介绍了Hive中一些常用的基本函数、炸裂函数和窗口函数的理论及使用,各位程序猿们需要多多练习函数的使用,体会函数的效果以及它们之间的联合使用!下期为大家介绍HIVE自定义函数的方法,实现我们自己想要的效果。
文章来源: https://study.disign.me/article/202508/7.hive-functions-in-depth.md
发布时间: 2025-02-20
作者: 技术书栈编辑