Hive函数

Hive 函数

1. Hive 函数分类

从输入输出的角度,可以将Hive的函数分为3类:标准函数、聚合函数、表生成函数

  • 标准函数:以一行中的一列或多列数据作为输入的参数且返回结果是一个值的函数。

    标准函数返回值只有一个,返回值类型为基本数据类型或复杂数据类型,如cast()

  • 聚合函数:以多行的零个或多个列的数据作为输入且返回单一值的函数。

    聚合函数常与 group by 子句结合使用。例如 sum(), count(), max()等

  • 表生成函数:接受零个或多个输入且产生多列或多行输出的函数。

1.1 查看函数命令

  • show functions 命令用于显示当前Hive会话中加载的所有函数,包括 内置函数、自定义函数

  • desc function function_namedesc function extended function_name 两个命令可以用于查看指定函数名称的描述,extended 关键字可以显示的更加详细

1.2 调用函数

​ 通过在查询语句中调用函数名,并传入参数来调用函数,函数的调用可以用于 selectwhere 子句中,包括以下3种典型情况:

(1) select concat(cola, colb) as x from table_name;

(2)select concat('abc', 'def');

(3)select * from table_name where length(col)<10;

2. Hive内置函数

  • 数据集:testData.txt

  • 创建数据库:create database wedw_tmp;

  • 创建数据表:tmp_url_info

hql 复制代码
create table tmp_url_info(
 user_id string comment "用户id",
 visit_url string comment "访问url",
 visit_cnt int comment "浏览次数/pv",
 visit_time timestamp comment "浏览时间",
 visit_date string comment "浏览日期"
)
row format delimited
fields terminated by ','
stored as textfile;

2.1 字符相关

​ 字符相关的函数侧重于对字符串进行处理。以下时使用频率高的字符函数。

concat

字符拼接,对多个字符串或二进制字符码按照参数顺序进行拼接。

concat(string|binary A, string|binary B...)

hql 复制代码
select concat('a','b','c');
abc
concat_ws

按照指定分隔符将字符或者数组进行拼接;第一个参数是分隔符。

concat_ws(string SEP, array)/concat_ws(string SEP, string A, string B...)

hql 复制代码
select concat_ws('','a','b','c')
a b c

#将数组列表元素按照指定分隔符拼接,类似于python中的join方法
select concat_ws('',array('a','b','c'))
a b c

select concat_ws(",",array('a','b','c'));
a,b,c
instr

查找字符串str中子字符串substr出现的位置,如果查找失败将返回0,如果任一参数为Null将返回null,注意位置为从1开始的,如果查找失败返回0

hql 复制代码
select 
 user_id,
 visit_time,
 visit_date,
 visit_cnt
from wedw_tmp.tmp_url_info
where instr(visit_time,'10')>0;
sql 复制代码
hive> select instr('abcd','a');
OK
1
length

统计字符串的长度 length(string a)

hql 复制代码
select length('abc');
3
trim

将字符串前后的空格去掉,和java中的trim方法一样,

sql 复制代码
#最后会得到sfssf sdf sdfds
select trim(' sfssf sdf sdfds '); 
upper

字符串中所有的字母转为大写 upper(string a)

hql 复制代码
select upper(concat_ws('', customer_fname, customer_lname)) as fullname from customers limit 10;
lower

字符串中所有的字母转为小写 lower(string a)

substr

截取字符串中从指定位置开始,指定长度的子字符串并返回,其中长度可选,默认截取到末尾。

substr(string a, int start, [int length ])

2.2 类型转换函数

  • cast(字段名 as 转换的类型) , 将 expr 的数据类型转换为 type 类型,如果转换失败,返回null
markdown 复制代码
CHAR[(N)] 字符型
DATE 日期型
DATETIME 日期和时间型
DECIMAL float型
SIGNED int
TIME 时间型
sql 复制代码
hive> select cast(round(9/3) as int);
OK
3

2.3 聚合函数

​ 聚合函数是在一组多行数据中进行计算并返回单一值的函数。常用的聚合函数如下:

count() sum() max() min() avg()

2.4 数学函数

round

round(double a) 返回对a四舍五入的BIGINT值

round(double a, int d) 返回对a四舍五入,保留d位小数的值

hql 复制代码
select round(4/3),round(4/3,2);
ceil

求不小于给定实数的最小整数;向上取整

ceil(double a), ceiling(double a)

sql 复制代码
  select ceil(4/3),ceiling(4/3);
  2
floor

对给定的实数向下取整

floor(double a)

hql 复制代码
select floor(4/3);

示例:对订单总金额进行四舍五入,要求精度位小数点后两位。

复制代码
select order_id, round(sum(cast(order_items.order_ite_subtotal as float)),2)
from orders join order_items on orders_id = order_items.order_item_order_id
group by order_id limit 10;

2.5 日期函数

from_unxitime

from_unixtime(bigint unixtime[, string format])

将时间的秒值转换成format格式(format可为"yyyy-MM-dd hh:mm:ss","yyyy-MM-dd hh","yyyy-MM-dd hh:mm"等等)

sql 复制代码
select from_unixtime(1599898989,'yyyy-MM-dd') as current_time
unix_timestamp

unix_timestamp():获取当前时间戳

unix_timestamp(string date):获取指定时间对应的时间戳

通过该函数结合from_unixtime使用,或者可计算两个时间差等

sql 复制代码
select 
 unix_timestamp() as current_timestamp,--获取当前时间戳
 unix_timestamp('2020-09-01 12:03:22') as speical_timestamp,--指定时间对于的时间戳
 from_unixtime(unix_timestamp(),'yyyy-MM-dd')  as current_date --获取当前日期
to_date

to_date(string timestamp)

返回时间字符串的日期部分

sql 复制代码
--最后得到2020-09-10
select to_date('2020-09-10 10:31:31') 
year

year(string date)

返回时间字符串的年份部分

sql 复制代码
--最后得到2020
select year('2020-09-02')
month

month(string date)

返回时间字符串的月份部分

sql 复制代码
--最后得到09
select month('2020-09-10')
day

day(string date)

返回时间字符串的天

sql 复制代码
--最后得到10
select day('2002-09-10')
date_add

date_add(string startdate, int days)

从开始时间startdate加上days

sql 复制代码
--获取当前时间下未来一周的时间
select date_add(now(),7) 
--获取上周的时间
select date_add(now(),-7)
date_sub

date_sub(string startdate, int days)

从开始时间startdate减去days

sql 复制代码
--获取当前时间下未来一周的时间
select date_sub(now(),-7) 
--获取上周的时间
select date_sub(now(),7)

示例:统计月度订单数量

hql 复制代码
select from_unxitime(unix_timestamp(order_date), "yyyy-MM") as year_month,
count(order_id) from orders 
group by from_unxitime(unix_timestamp(order_date), "yyyy-MM")

2.6 条件函数

if

if(boolean testCondition, T valueTrue, T valueFalseOrNull):判断函数,很简单

如果testCondition 为true就返回valueTrue,否则返回valueFalseOrNull

sql 复制代码
--判断是否为user1用户
select 
  distinct user_id,
  if(user_id='user1',true,false) as flag
from wedw_tmp.tmp_url_info 
case when

CASE a WHEN b THEN c [WHEN d THEN e] [ELSE f] END

如果a=b就返回c,a=d就返回e,否则返回f 如CASE 4 WHEN 5 THEN 5 WHEN 4 THEN 4 ELSE 3 END 将返回4

相比if,个人更倾向于使用case when

sql 复制代码
--仍然以if上面的列子
select 
  distinct user_id,
  case when user_id='user1' then 'true'
     when user_id='user2' then 'test'
  else 'false' end  as flag
from wedw_tmp.tmp_url_info 
coalesce

COALESCE(T v1, T v2, ...)

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

sql 复制代码
--该函数结合lead或者lag更容易贴近实际业务需求,这里使用lead,并取后3行的值作为当前行值
select 
  user_id,
  visit_time,
  rank,
  lead_time,
  coalesce(visit_time,lead_time) as has_time
from 
(
  select
  user_id,
  visit_time,
  visit_cnt,
  row_number() over(partition by user_id order by visit_date desc) as rank,
  lead(visit_time,3) over(partition by user_id order by visit_date desc) as lead_time
  from  wedw_tmp.tmp_url_info
  order by user_id
)t;
sql 复制代码
hive> select coalesce(null,'aa');
OK
aa

示例:根据商品价格将商品分为3个级别:0~100, 100~200及200以上,并分别统计各档商品个数

hql 复制代码
select level, count(*) from (select *, case when product_price<100 then 1
when product_price between 100 and 200 then 2
else 3 end as level
from products) as a 
group by level;

2.7 集合函数

collect_set

将分组内的数据放入到一个集合中,具有去重的功能;

sql 复制代码
create table collect_set (name string, area string, course string, score int);

insert into table collect_set values('zhang3','bj','math',88);

insert into table collect_set values('li4','bj','math',99);

insert into table collect_set values('wang5','sh','chinese',92);

insert into table collect_set values('zhao6','sh','chinese',54);

insert into table collect_set values('tian7','bj','chinese',91);

--把同一分组的不同行的数据聚合成一个集合
select course,collect_set(area),avg(score)from collect_set group by course;

OK
chinese ["sh","bj"]     79.0
math    ["bj"]  93.5

--用下标可以取某一个
select course,collect_set(area)[1],avg(score)from collect_set group by course;

OK
chinese sh      79.0
math    bj      93.5
sql 复制代码
--统计每个用户具体哪些天访问过
select
  user_id,
  collect_set(visit_date) over(partition by user_id) as visit_date_set 
from wedw_tmp.tmp_url_info
collect_list

和collect_set一样,但是没有去重功能

sql 复制代码
select
  user_id,
  collect_set(visit_date) over(partition by user_id) as visit_date_set 
from wedw_tmp.tmp_url_info
sort_array

数组内排序;通常结合collect_set或者collect_list使用;

如collect_list为例子,可以发现日期并不是按照顺序组合的,这里有需求需要按照时间升序的方式来组合

sql 复制代码
--按照时间升序来组合
select
  user_id,
  sort_array(collect_list(visit_date) over(partition by user_id)) as visit_date_set 
from wedw_tmp.tmp_url_info;

--按照时间降序排序
select
  user_id,
  collect_list(visit_date) over(partition by user_id order by visit_date desc) as visit_date_set 
from wedw_tmp.tmp_url_info;
size

是用来统计数组或者map的元素,通常笔者用该函数用来统计去重数(一般都是通过distinct,然后count统计,但是这种方式效率较慢)

sql 复制代码
--使用size
select 
   distinct size(collect_set(user_id) over(partition by year(visit_date)))
from wedw_tmp.tmp_url_info;


--使用通过distinct,然后count统计的方式
select 
  count(1)
from 
(
  select 
    distinct user_id
  from wedw_tmp.tmp_url_info 
)t;
explode

列转行,通常是将一个数组内的元素打开,拆成多行

sql 复制代码
--简单例子
select  explode(array(1,2,3,4,5))

--结合lateral view 使用
select 
  get_json_object(user,'$.user_id')
from 
(
  select 
   distinct collect_set(concat('{"user_id":"',user_id,'"}')) over(partition by year(visit_date)) as user_list
  from wedw_tmp.tmp_url_info
)t
lateral view explode(user_list) user_list as user
相关推荐
LaughingZhu32 分钟前
移动端 AI 的价值重估:设备端智能的拐点
大数据·人工智能·经验分享·搜索引擎·语音识别
@insist1231 小时前
网络工程师-WLAN 无线局域网全解析
大数据·网络·网络工程师·软考·软件水平考试
airuike1233 小时前
以微见著,精准护航:MEMS IMU助力高铁轨道智能检测
大数据·人工智能·科技
青稞社区.4 小时前
Claude Code 源码深度解析:运行机制与 Memory 模块详解
大数据·人工智能·elasticsearch·搜索引擎·agi
T06205144 小时前
【面板数据】地级市及区县人口空心化数据(2000-2024年)
大数据
Aktx20FNz5 小时前
iFlow CLI 完整工作流指南
大数据·elasticsearch·搜索引擎
LaughingZhu6 小时前
Anthropic 收购 Oven 后,Claude Code 用运行时写了一篇护城河文章
大数据·人工智能·经验分享·搜索引擎·语音识别
学习3人组6 小时前
TortoiseGit冲突解决实战上机练习
大数据·elasticsearch·搜索引擎
Ln5x9qZC26 小时前
Flink SQL 元数据持久化实战
大数据·sql·flink
OYpBNTQXi6 小时前
Flink Agents 源码解读 --- (6) --- ActionTask
大数据·flink