Day05-Hive常用函数

  • 函数:提前组织好的,可以重复使用的,具有特定功能的代码块
  • Hive函数有上百种,详细的函数可以看官方文档:

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF#LanguageManualUDF-MathematicalFunctions

目录

一、函数分类标准

1、内置函数

2、自定义函数

二、一些常见函数的使用

1、复杂类型函数

①array类型——数组类型

②map类型——映射类型(键值对)

③struct类型——结构类型

2、字符串函数

常见字符串函数

①concat:字符串紧凑拼接到一起生成新字符串

②concat_ws:字符串用指定分隔符拼接到一起生成新字符串

③length:获取字符串长度

④lower: 把字符串中的字母全部变成小写

⑤upper:把字符串中的字母全部变成大写

⑥trim:把字符串两端的空白去除

其他字符串函数

①substr—— 截取字符串 

②replace——替换字符串 

③regexp_replace——正则替换字符串

④parse_url—— 解析url(统一资源定位符)

⑤get_json_object—— 获取json对象解析对应数据

3、日期时间函数

①日期:获取指定的时间的年月日...

②current_timestamp:获取当前时间戳(时间原点到现在的秒/毫秒)

③unix_timestamp:获取当前时间戳(时间原点到现在的秒/毫秒)

④from_unixtime:把unix时间戳转换为日期格式的时间 

⑤current_date:获取当前日期(年月日) 

⑥to_date:字符串格式时间戳转日期(年月日)

⑦datediff:获取两个指定时间的差值

⑧date_add:在指定日期时间上加几天

⑨date_sub:在指定日期时间上减几天

4、数字函数

①round: 指定小数保留位数 

②rand: 生成0-1的随机数

③pi: 生成π结果

④ceil: 向上取整——floor: 向下取整

5、条件函数

①if(条件判断,true的时候执行此处,false的时候执行此处)

②isnull(数据) :判断是否为空

③isnotnull(数据):判断是否为空

④nvl(数据,参数2):如果数据不为空打印数据,为空null打印第二个参数    

⑤coalesce(参数1,参数2...):返回第一个不是null的值

⑥条件转换函数格式

6、类型转换函数——cast(数据 as 要转换的类型)

7、数据脱敏函数

①mask_hash:返回指定字符串的hash编码    

②mask: 覆盖值

③mask_first_n(string str[, int n]:对前n个进行脱敏替换

④mask_show_first_n(string str[, int n]):除了前n个字符,其余进行掩码处理

⑤mask_last_n(string str[, int n]): 对后n个进行脱敏替换

⑥mask_show_last_n(string str[, int n]):除了后n个字符,其余进行掩码处理

8、炸裂函数——explode(容器)

9、开窗函数

常用开窗函数

与SQL相同的开窗函数(在sql查询篇)

开窗函数控制范围

其他开窗函数

①ntile(x)功能: 将分组排序之后的数据分成指定的x个部分(x个桶)

②lag: 用于统计窗口内往上第n行值

③lead: 用于统计窗口内往下第n行值

④first_value: 取分组内排序后,截止到当前行,第一个值

⑤last_value : 取分组内排序后,截止到当前行,最后一个值

10、其他函数

另:行转列、列转行

行转列

列转行


一、函数分类标准

1、内置函数

内置函数是Hive提供的一组预定义函数,如数值函数、集合函数、类型函数、字符串函数等。

查看所有函数:

show functions;

查看某函数使用帮助文档: desc function extended 函数名;       (extended关键字能查看详细信息示例,可以加可以不加)

如:

describe function extended avg;

运行结果:

翻译:

2、自定义函数

目前hive三大标准

UDF:(User-Defined-Function)普通函数:  特点是一进一出(输入一行数据输出一行数据)       如: split
UDAF:(User-Defined Aggregation Function)聚合函数: 特点是多进一出(输入多行输出一行)  如: count sum max  min  avg
UDTF:(User-Defined Table-Generating Functions)表生成函数:  特点是一进多出(输入一行输出多行)   如: explode

二、一些常见函数的使用

查询所有hive函数名称
    

show function;

查看某函数使用文档
extended可加可不加,加上extended关键字能查看详细信息示例
  

 desc function extended 函数名; 

1、复杂类型函数

①array类型——数组类型

取值: 字段名[索引]   注意: 索引从0开始

如查询数组

select array('caijiuduolian','666','888');

获取长度的函数: size(字段名)       

如查询数组长度
        

select size(array('caijiuduolian','666','888'));

判断是否包含某个数据的函数: array_contains(字段名,某数据) 
如查询这个数组中是否有这个数据——运行得到true

select array_contains(array('caijiuduolian','666','888'),'caijiuduolian');

对数组进行排序的函数: sort_array(数组)

对这个数组排序——运行得到 [1,2,3,4,5]
 

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

②map类型——映射类型(键值对)

取值: 字段名[key]——类似于根据键查询
          

 select map('a',1,'b',2,'c',3);

 获取长度的函数: size(字段名)—— 查询键值对长度

select size(map('a',1,'b',2,'c',3));

获取所有key的函数: map_keys() —— 查询所有的键,运行得到 ["a","b","c"]
 

 select map_keys(map('a',1,'b',2,'c',3));

获取所有value的函数: map_values()——查询所有的值,运行得到[1,2,3]      
 

 select map_keys(map('a',1,'b',2,'c',3));

③struct类型——结构类型

取值: 字段名.子字段名n


2、字符串函数

常见字符串函数

①concat:字符串紧凑拼接到一起生成新字符串

--如:运行得到 'duolian666888'

select concat('duolian', '666', '888'); 

②concat_ws:字符串用指定分隔符拼接到一起生成新字符串

--如: 运行得到'duolian-666-888'

select concat_ws('-', 'duolian', '666', '888');

③length:获取字符串长度

--如:运行得到7

select length('cai-666');

④lower: 把字符串中的字母全部变成小写

--如:运行得到'cai-666'

select lower('CAI-666');

⑤upper:把字符串中的字母全部变成大写

--如:运行得到'CAI-666'

select upper('cai-666');

⑥trim:把字符串两端的空白去除

--如:运行得到'cai 666'
select trim('   cai666  ');

另外:
rtrim:去掉字符串右端空白
ltrim:去掉字符串左端空白


其他字符串函数

①substr—— 截取字符串 

格式: substr(字符串,开始索引,截取长度): 截取字符串,截取长度如果不写默认到结尾

        select substr('2023-05-21',1,4); -- 结果2023
        select substr('2023-05-21',1,7); -- 结果2023-05
        select substr('2023-05-21',6,2); -- 结果05
        select substr('2023-05-21',-2,2); -- 结果21
--substr经常用于截取日期中的年月
            select substr(`current_date`(),1,7);

②replace——替换字符串 

replace(大字符串,敏感词,替换后的内容):

 select replace('你靓仔哦','靓仔','菜');--将靓仔替换为菜

③regexp_replace——正则替换字符串

格式:regexp_replace(str, regexp, rep)

--\d+ 表示匹配一个或多个连续的数字字符,第一个\表示转义,因为\d有特殊含义会识别不到,\\d后就变成识别0-9的数字

--如下,
select regexp_replace('cai-666', '\\d+', 'num');

另:解析函数:regexp_extract(str, regexp[, idx])
正则中()代表分组,自动从1开始生成编号,提取正则匹配到的指定组内容

--运行得到888,其中 '(\\d+)-(\\d+)'为捕获两个数字序列,888为第二个数字序列
select regexp_extract('duolian-666-888', '(\\d+)-(\\d+)', 2);

④parse_url—— 解析url(统一资源定位符)

协议/主机地址:端口号/资源路径?查询参数

-- 返回URL的主机部分: www.caijiuduolian.cn
select parse_url('http://www.caijiuduolian.cn/path/cai.html?user=cai&pwd=123', 'HOST');

--返回URL的路径部分:/path/cai.html

select parse_url('http://www.caijiuduolian.cn/path/cai.html?user=cai&pwd=123', 'PATH');
-- 返回URL的查询字符串部分:user=cai&pwd=123
select parse_url('http://www.caijiuduolian.cn/path/cai.html?user=cai&pwd=123', 'QUERY');

--返回URL查询字符串中名为user的参数值:cai
select parse_url('http://www.caijiuduolian.cn/path/cai.html?user=cai&pwd=123', 'QUERY', 'user');
--返回URL查询字符串中名为pwd的参数值:123
select parse_url('http://www.caijiuduolian.cn/path/cai.html?user=cai&pwd=123', 'QUERY', 'pwd');

⑤get_json_object—— 获取json对象解析对应数据

格式:get_json_object(json_txt, path)

整个json字符串用单引号'包裹, json字符串中的键, 值用双引号"包裹.
json字符串的格式: {键:值, 键: 值}
json数组的格式: [{键:值, 键: 值}, {键:值, 键: 值}, {键:值, 键: 值}] 

-- 运行得到杨, $表示json对象
select get_json_object('{"name":"杨", "age":"18"}', '$.name');     

-- 运行得到{"name":"杨", "age":"18"}

select get_json_object('[{"name":"杨", "age":"18"}, {"name":"小龙", "age":"26"}]', '$.[0]'); 

-- 运行得到小龙,   $表示json对象

select get_json_object('[{"name":"杨", "age":"18"}, {"name":"小龙", "age":"26"}]', '$.[1].name'); 

3、日期时间函数

①日期:获取指定的时间的年月日...

--如:运行得到2023

select year('2023-05-21 11:19:31.222000000'); 

year: 获取指定日期时间中的年       
month:获取指定日期时间中的月        
day:获取指定日期时间中的日         
hour:获取指定日期时间中的时
minute:获取指定日期时间中的分
second:获取指定日期时间中的秒
dayofmonth: 获取指定日期时间中的月中第几天
dayofweek:获取指定日期时间中的周中第几天
quarter:获取指定日期时间中的所属季度
weekofyear:获取指定日期时间中的年中第几周

②current_timestamp:获取当前时间戳(时间原点到现在的秒/毫秒)

获取时间原点到现在的秒/毫秒,底层自动转换方便查看的日期格式

select current_timestamp();

③unix_timestamp:获取当前时间戳(时间原点到现在的秒/毫秒)

--格式
select unix_timestamp();
--如: 可以使用yyyyMMdd HH:mm:ss进行格式化转换
select unix_timestamp('2023-05-21 11:38:56','yyyy-MM-dd HH:mm:ss'); 

④from_unixtime:把unix时间戳转换为日期格式的时间 

如果传入的参数是0,获取的是时间原点1970-01-01 00:00:00

--如:
select from_unixtime(1684669136); -- 2023-05-21 11:38:56
--获取时间原点日期
select from_unixtime(0); -- 1970-01-01 00:00:00

⑤current_date:获取当前日期(年月日) 

--如:
select from_unixtime(1684669136); -- 2023-05-21 11:38:56
--获取时间原点日期
select from_unixtime(0); -- 1970-01-01 00:00:00

⑥to_date:字符串格式时间戳转日期(年月日)

--手动输入或用时间戳转
select to_date('2023-05-21 11:19:31.222000000');
select to_date(current_timestamp());

⑦datediff:获取两个指定时间的差值

--如:当前日期和2023-11-03的时间差

select datediff(`current_date`(),'2023-11-03'); 

⑧date_add:在指定日期时间上加几天

-- 获取明天的日期
select date_add(current_timestamp(),1);

--获取昨天的日期
select date_add(current_timestamp(),-1);

⑨date_sub:在指定日期时间上减几天

--获取明天的日期
select date_sub(current_timestamp(),-1);
-- 获取昨天的日期
select date_sub(current_timestamp(),1);

4、数字函数

①round: 指定小数保留位数 

四舍五入设置保留位数

--如:运行得到3.1416

select round(pi(),4);

②rand: 生成0-1的随机数

应用解决数据倾斜问题,可以把之前大量相同的值后面拼接随机数

--如:可能得到0.1112324354643242

select rand();

③pi: 生成π结果

select pi();

④ceil: 向上取整——floor: 向下取整

--如:运行得到4
select ceil(pi());

--如:运行得到3
select floor(pi());

5、条件函数

①if(条件判断,true的时候执行此处,false的时候执行此处)

select if(10 > 5, '真', '假'); -- 真

②isnull(数据) :判断是否为空

为空: true 
不为空:false   

 select isnull(null); -- true

③isnotnull(数据):判断是否为空

为空null:false
不为空: true 

select isnotnull('菜就多练'); -- true

④nvl(数据,参数2):如果数据不为空打印数据,为空null打印第二个参数    

--如:为空打印666
select nvl(null,'666');
--如:不为空打印cai
select nvl('cai','666');

⑤coalesce(参数1,参数2...):返回第一个不是null的值

从左到右依次查找,返回第一个不是null的值,如果找到最后都是null,就返回null 

    select COALESCE(null,11,22,33);-- 11
    select COALESCE(null,null,22,33);--22
    select COALESCE(null,null,null,33);--33
    select COALESCE(null,null,null,0);--0
    select COALESCE(null,null,null,null);--null

条件转换函数格式

--case给值判断
    select
       case 7
           when 1 then '周一上班'
           when 2 then '周二上班'
           when 3 then '周三上班'
           when 4 then '周四上班'
           when 5 then '周五上班'
           when 6 then '周六休息'
           when 7 then '周日休息'
           else '老弟啊,你是外星人吗?'
       end;
--一个一个判断是否等于
    select
       case
           when 7==1 then '周一上班'
           when 7==2 then '周二上班'
           when 7==3 then '周三上班'
           when 7==4 then '周四上班'
           when 7==5 then '周五上班'
           when 7==6 then '周六休息'
           when 7==7 then '周日休息'
           else '老弟啊,你是外星人吗?'
       end;

6、类型转换函数——cast(数据 as 要转换的类型)

 select cast(3.14 as int); -- 3
    select cast(3.14 as string) ; -- '3.14'
    select cast('3.14' as float); -- 3.14
    select cast('3.14' as int); -- 3
    select cast('binzi' as int); -- null

应用场景:concat_ws要求被连接的必须是字符串,如果直接用666就报错
 

--如以下代码会报错,因为concat_ws只能拼接字符串类型
select concat_ws('_','cai',666,'888'); 
--转换后,得到cai_666_888
select concat_ws('_','cai',cast(666 as string),'888'); 

7、数据脱敏函数

①mask_hash:返回指定字符串的hash编码
    

select mask_hash('cai');

②mask: 覆盖值

将查询回的数据,大写字母转换为X,小写字母转换为x,数字转换为n。

--如,运行得到xxxnnnXXX
select mask("abc123DEF");
--自定义替换的字母: 依次为大写小写数字,运行得到小小小数数数大大大
select mask("abc123DEF",'大','小','数');
--运行得到...%%%///
select mask("abc123DEF",'/','.','%');

③mask_first_n(string str[, int n]:对前n个进行脱敏替换

大写字母转换为X,小写字母转换为x,数字转换为n。

--如:换前6个,得到xxxnnnDEF
select mask_first_n("abc123DEF",6);

④mask_show_first_n(string str[, int n]):除了前n个字符,其余进行掩码处理

--如:除了前6个都换,得到abc123XXX
select mask_show_first_n("abc123DEF",6);

⑤mask_last_n(string str[, int n]): 对后n个进行脱敏替换


--如:换后6个,得到abcnnnXXX

select mask_last_n("abc123DEF",6);

⑥mask_show_last_n(string str[, int n]):除了后n个字符,其余进行掩码处理

--如:除了后6个都换,xxx123DEF

select mask_show_last_n("abc123DEF",6);

8、炸裂函数——explode(容器)

把一个容器的多个数据炸裂出单独展示:  
炸裂函数一般配合侧视图使用,属于UDTF—一进多出

--格式:

select 原表别名.字段名,侧视图名.字段名 from 原表 原表别名 lateral view explode(要炸开的字段) 侧视图名 as 字段名 ;
--如:拆数组
select explode(array('cai', '666', '888'));

--如: 拆键值对
select explode(map('a', 1, 'b', 2, 'c', 3));
--实例: 先使用炸裂函数测试是否能够变成多行,再使用侧视图保证炸裂结果和原表数据同时展示

select col1,col2,lv.col33 from col2row2 lateral view explode(split(col3,',')) lv as col33;

9、开窗函数

窗口函数结果都是单独生成一列存储对应数据

常用开窗函数

与SQL相同的开窗函数(在sql查询篇)

开窗函数可以与分组、排序关键字配合使用

开窗函数控制范围

unbounded: 无界限
x preceding:往前x行
x following:往后x行
current row:当前行
unbounded preceding :表示从前面的起点  第一行
unbounded following :表示到后面的终点  最后一行  

例子:

--默认从第一行到当前行
select cookieid,createtime,pv,
       sum(pv) over(partition by cookieid order by createtime) as pv1
from website_pv_info;

--第一行到当前行 等效于rows between不写 默认就是第一行到当前行
select cookieid,createtime,pv,
       sum(pv) over(partition by cookieid order by createtime rows between unbounded preceding and current row) as pv2
from website_pv_info;


--向前3行至当前行
select cookieid,createtime,pv,
       sum(pv) over(partition by cookieid order by createtime rows between 3 preceding and current row) as pv4
from website_pv_info;

--向前3行 向后1行
select cookieid,createtime,pv,
       sum(pv) over(partition by cookieid order by createtime rows between 3 preceding and 1 following) as pv5
from website_pv_info;

--当前行至最后一行
select cookieid,createtime,pv,
       sum(pv) over(partition by cookieid order by createtime rows between current row and unbounded following) as pv6
from website_pv_info;

--第一行到最后一行 也就是分组内的所有行
select cookieid,createtime,pv,
       sum(pv) over(partition by cookieid order by createtime rows between unbounded preceding  and unbounded following) as pv6
from website_pv_info;

其他开窗函数

①ntile(x)功能: 将分组排序之后的数据分成指定的x个部分(x个桶)

  ntile规则:尽量平均分配 ,优先满足最小(编号1)的桶,彼此最多不相差1个。

--把每个分组内的数据分为3桶
SELECT
    cookieid,
    createtime,
    pv,
    ntile(3) OVER(PARTITION BY cookieid ORDER BY createtime) AS rn2
FROM website_pv_info
ORDER BY cookieid,createtime;

②lag: 用于统计窗口内往上第n行值

--lag 用于统计窗口内往上第n行值
select cookieid, createtime, url,
    row_number() over (partition by cookieid order by createtime) rn,
    lag(createtime, 1) over (partition by cookieid order by createtime) la1,
    lag(createtime, 2, '2000-01-01 00:00:00') over (partition by cookieid order by createtime) la2
from website_url_info;

③lead: 用于统计窗口内往下第n行值

--lead 用于统计窗口内往下第n行值
select cookieid, createtime, url,
    row_number() over (partition by cookieid order by createtime) rn,
    lead(createtime, 1) over (partition by cookieid order by createtime) la1,
    lead(createtime, 2, '2000-01-01 00:00:00') over (partition by cookieid order by createtime) la2
from website_url_info;

④first_value: 取分组内排序后,截止到当前行,第一个值

--FIRST_VALUE 取分组内排序后,截止到当前行,第一个值
select cookieid, createtime, url,
    row_number() over (partition by cookieid order by createtime) rn,
    first_value(url) over (partition by cookieid order by createtime) fv
from website_url_info;

⑤last_value : 取分组内排序后,截止到当前行,最后一个值

--LAST_VALUE  取分组内排序后,截止到当前行,最后一个值
select cookieid, createtime, url,
    row_number() over (partition by cookieid order by createtime) rn,
    last_value(url) over (partition by cookieid order by createtime rows between unbounded preceding and unbounded following) fv
from website_url_info;

10、其他函数

①hash——取哈希值函数

select hash("cai");

②md5(string/binary)—— MD5加密
结果是32位的

 select md5("cai");

③ sha1(string/binary)——SHA-1加密

结果是40位的

select sha1("cai"); 

④sha2(string/binary, int)  ——SHA-2家族算法加密
    (SHA-224, SHA-256, SHA-384, SHA-512)

select sha2("cai",224);
select sha2("cai",512);

⑤crc32加密
    

select crc32("cai"); 

⑥获取当前用户、登录用户、当前数据库和数据库版本信息

其中

    current_user():返回执行当前查询的用户的名称。
    logged_in_user():返回当前登录用户的用户名
    current_database():返回当前正在使用的数据库的名称。
    version():返回数据库管理系统的版本信息。

select current_user(),logged_in_user(),current_database(),version();

另:行转列、列转行

行转列

collect_set(字段名): 把多个数据收集到一起,默认去重
collect_list(字段名): 把多个数据收集到一起,默认不去重
把多个子串用指定分隔符拼接成一个大字符串: concat_ws(分隔符,多个数据...)      注意: 如果拼接数据不是字符串可以使用cast转换

--建表
create table row2col2(
                         col1 string,
                         col2 string,
                         col3 int
)row format delimited fields terminated by '\t';

--加载数据到表中
--数据为以下
a	b	1
a	b	2
a	b	3
c	d	4
c	d	5
c	d	6

-- 验证数据
select * from row2col2;
/*
需求1: 把原表数据变成以下格式
a b [1,2,3]
c d [4,5,6]
*/
select
    col1,
    col2,
    collect_list(col3)
from
    row2col2
group by
    col1, col2;

/*
需求2: 把原表数据变成以下格式
a b '1-2-3'
c d '4-5-6'
*/
select
    col1,
    col2,
    concat_ws('-',collect_list(cast(col3 as string)))
from
    row2col2
group by
    col1, col2;

列转行

把字符串按照指定分隔符切割: split(字符串,分隔符)

炸裂函数配合侧视图使用格式: select 原表别名.字段名,侧视图名.字段名 from 原表 原表别名 lateral view explode(要炸开的字段) 侧视图名 as 字段名 ;

--创建表
create table col2row2(
                         col1 string,
                         col2 string,
                         col3 string
)row format delimited fields terminated by '\t';

--加载数据
--以下为数据
a	b	1,2,3
c	d	4,5,6

-- 验证数据
select * from col2row2;


-- 单列数据先切割再炸开
select split(col3,',') from col2row2;
select explode(split(col3,',')) from col2row2;

-- 再去完成需求,列转行生成最后完整表
select col1,col2,tmp.col3
from col2row2
 lateral view explode(split(col3,',')) tmp as col3;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值