Hive函数深度讲解之单行函数、聚合函数、炸裂函数、窗口函数

前言

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主要用于和splitexplode等用户自定义表生成函数(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 子句和窗口子句都缺失时,窗口范围是从无上限边界到无下限边界。
  • 并非所有函数都需要指定窗口子句。像 rankdense_rankntilerow_numberlaglead 这些函数是不支持使用窗口子句的。
  • 在使用排名分析函数时,通常不需要传入额外的参数,这些函数会自动对排好序的数据进行编号。

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

作者: 技术书栈编辑