hive substr函数_数据分析工具篇——HQL函数及逻辑
本篇文章我们梳理一下hive常用的函数,对于hive而言,常用的函数并不是特别多,往往记住关键几个,就可以解决80%的问题,这也是大家喜欢hive的原因,那么,常用的函数有哪些呢?
时间函数
1)时间格式转化
常用的日期格式主要有两个:时间戳和日期格式,时间戳便于计算,日期格式便于阅读,两者各有利弊,所以需要相互转换,转换的对应函数主要有:
from_unixtime(timestamp,dateformat):将时间戳转化为日期格式,格式必须是10位,毫秒级的时间戳需要用cast转化成秒级。unix_timestamp(date,dateformat):日期格式转化为时间戳,如果括号内没有参数则表示返回当前的时间戳。
例如:
时间戳转日期格式:
select from_unixtime(unix_timestamp(),'yyyy-MM-dd HH:mm:ss') as date_time, from_unixtime(1537924406,'yyyy-MM-dd') as date_time1from dual;
如果时间戳是毫秒级,则字段修改为:
from_unixtime(cast(unix_timestamp()/1000 as int),'yyyy-MM-dd HH:mm:ss') as date_time
日期格式转时间戳:
select unix_timestamp() as time_stamp, --返回当前时间戳; unix_timestamp('2018-09-26 9:13:26','yyyy-MM-ddHH:mm:ss') as time_stamp1from dual;
作为一个数据,在不同系统之间游走,有没有经常遇到时间格式不匹配的情况,所以需要做格式的转化:
date_format(string/date,dateformate):把字符串或者日期转成指定格式的日期。
日期格式调整:
select date_format('2018-09-12','yyyy-MM-dd HH:mm:ss') as date_time, date_format('2018-09-12','yyyyMMdd') as date_time1from dual;--2018-09-12 00:00:00
有没有发现一个问题,date_format只能从yyyy-MM-dd格式转化成其他格式,对于其他类型,例如:yyyyMMdd,则不能处理,所以需要灵活一点,将各个格式的时间转化成时间戳,再通过时间戳转化成其他格式:
select from_unixtime(unix_timestamp(substr('20191007000000',1,8),'yyyyMMdd'),'yyyy-MM-dd');
如此一来,各种格式都可以转化。
2)日期的加减差运算:
日期的加减是对日期格式数据的基本运算,常用的是时间差计算、加一天、减一天等。
时间差计算:
datediff(date,date1);日期差,即两个日期差几天。months_between(date,date1);两个日期差几个月,用法一致。select datediff('2015-05-22','2015-05-29') as date_ff; --[-7]
在原日期上加n天:
date_add:在现在日期上增加天数,
add_months是增加月份,用法一致。
select date_add('2015-05-22 15:34:23',2); --2015-05-24
在原日期上减n天:
date_sub:在现在日期上减少天数。
select date_sub('2015-05-22 15:34:23',2); --2015-05-20
3)时间截取:
如果我们获取到一个完整的时间,但是只想用其中的一部分,势必牵扯到时间截取的功能,常见的时间截取主要是如下几个函数:
to_date:获取完整时间中的日期部分:
select to_date('2015-06-01 15:34:23'); --2015-06-01
year:获取完整时间中的年份:
select year('2015-05-22 15:34:23'); --2015
month:获取完整时间中的月份:
select month('2015-05-22 15:34:23'); --5
day:获取完整时间中的日期:
select day('2015-05-22 15:34:23'); --22
4)日期中其他灵活操作:
日期除了计算多少天,截取某一段,还会牵扯一些比较灵活的操作方法,例如:判断当天是周几,判断年周、月周,当月的最后一天和第一天,下n天,上n天等。
获取一年中的第几周:weekofyear:
select weekofyear('2015-05-22 15:34:23'); --21
获取当月中的第几周:
select weekofyear('2015-05-22')-weekofyear(trunc('2015-05-22', ‘MM’))+1;
这其中有一个有意思的点:每一周是按照周一到周日为一个完整周,与英美的周日到周六的逻辑有些不一样,所以在如下日历中:
11月1日为周日,按照代码中的逻辑与10月31日是一周。
判断当天为周几:
Select 8-datediff(next_day(‘2020-12-20’, ‘MO’), ‘2020-12-20’) as week;
获取月末最后一天:
last_day(date):
select last_day('2018-09-30') as date_time, last_day('2018-09-27 21:16:13') as date_time1from dual;--2018-09-30
获取月初、年初:
trunc(date,format)
format:MONTH/MON/MM, YEAR/YYYY/YY
select trunc('2018-09-27','YY') as date_time,--返回年初 trunc('2018-09-27 21:16:13','MM') as date_time1 --返回月初from dual;--2018-01-01和2018-09-01
当前日期下个星期X的日期:
next_day(date,formate) format:英文星期几的缩写或者全拼。
select next_day('2018-09-27','TH') as date_time, next_day('2018-09-27 21:16:13','TU') as date_time1from dual;--2018-10-04和2018-10-02
汇总SQL为(下文SQL为对应的日期写法,可以作为上面简单罗列的补充版):
select day -- 时间 ,date_add(day,1 - dayofweek(day)) as week_first_day -- 本周第一天_周日 ,date_add(day,7 - dayofweek(day)) as week_last_day -- 本周最后一天_周六 ,date_add(day,1 - case when dayofweek(day) = 1 then 7 else dayofweek(day) - 1 end) as week_first_day -- 本周第一天_周一 ,date_add(day,7 - case when dayofweek(day) = 1 then 7 else dayofweek(day) - 1 end) as week_last_day -- 本周最后一天_周日 ,next_day(day,'TU') as next_tuesday -- 当前日期的下个周二 ,trunc(day,'MM') as month_first_day -- 当月第一天 ,last_day(day) as month_last_day -- 当月最后一天 ,to_date(concat(year(day),'-',lpad(ceil(month(day)/3) * 3 -2,2,0),'-01')) as season_first_day -- 当季第一天 ,last_day(to_date(concat(year(day),'-',lpad(ceil(month(day)/3) * 3,2,0),'-01'))) as season_last_day -- 当季最后一天 ,trunc(day,'YY') as year_first_day -- 当年第一天 ,last_day(add_months(trunc(day,'YY'),12)) as year_last_day -- 当年最后一天 ,weekofyear(day) as weekofyear -- 当年第几周 ,second(day) as second -- 秒钟 ,minute(day) as minute -- 分钟 ,hour(day) as hour -- 小时 ,day(day) as day -- 日期 ,month(day) as month -- 月份 ,lpad(ceil(month(day)/3),2,0) as season -- 季度 ,year(day) as year -- 年份from ( select '2018-01-02 01:01:01' as day union all select '2018-02-02 02:03:04' as day union all select '2018-03-02 03:05:07' as day union all select '2018-04-02 04:07:10' as day union all select '2018-05-02 05:09:13' as day union all select '2018-06-02 06:11:16' as day union all select '2018-07-02 07:13:19' as day union all select '2018-08-02 08:15:22' as day union all select '2018-09-02 09:17:25' as day union all select '2018-10-02 10:19:28' as day union all select '2018-11-02 11:21:31' as day union all select '2018-12-02 12:23:34' as day) t1;
数据运算总结
Hive中数据一般是可以用常规的运算符号表示的,例如:“加减乘除”用“+-*/”表示,但是对于初次之外的运算需要用到对应的函数:
sum():求和;count():求数据量;avg():求平均值;distinct:求不同值数(去重);min:求最小值;max:求最大值;pmod(int a, int b):返回a除以b的余数的绝对值;round:四舍五入 select round(数值,小数点位数);ceil:向上取整 select ceil(45.6); floor:向下取整 select floor(45.6);
在数据运算过程中经常会遇到用字符串形式存储的数值,计算过程中需要将其转化成数值型,然后进行运算,其中运算方法为:
cast(aaa as int):将string转化成int;cast(aaa as decimal(10, 2)):将string转化成float,保留两位小数;
当然也可以将数值转化成字符串:
cast(aaa as string):将int转化成string;
除了上面这些方法外,hive在数据运算方面还有大于、小于、等于等操作,这些操作都有对应的运算符号表示,在此就不多描述了。
字符串操作总结
字符串可以说是最常用的处理思路,在特征处理、数据清洗过程中高频使用,这些函数用的好会为接下来数据建模、统计运算带来极大便利。下面我们来梳理一下常用的字符串处理方法:
1)空格处理:
trim(String A):去除A两侧的空格;ltrim(String A):去除左边空格;rtrim(String A):去除右边空格select trim('abc') from lxw_dual;
2)单个字符串操作:
reverse('abcde')=edcba:字符串反转
lower:转成小写
select lower('Hive'); --hive
upper:转成大写
select lower('Hive'); --HIVE
length:长度
select length('Hive'); --4
substr:求子串
select substr('hive',2); --iveselect substr('hive',2,1); --i
lpad:左填充
对hive填充到10位,补位用#
select lpad('hive',10,'#'); --######hive
rpad:右填充
select rpad('hive',10,'#'); --hive######
regexp_extract():正则表达式处理
regexp_extract(string subject, string pattern, int index); --函数的应用;
将字符串subject按照pattern正则表达式的规则拆分,返回index指定的字符:
select clientcode, regexp_extract(filterlist,'(filtertype"\\:")(\\d+)(",)',2) as filtertypefrom tmp_action_click
在正则表达式中,经常会用到贪心算法(.*?)和非贪心算法(.*)用法,用来清洗字符串中的内容。
正则表达式替换函数:
regexp_replace('foobar','oo|ar','')=fb #替换oo|ar为空字符
有意思的是,hive中并没有直接的replace函数,如果是整个字符串的判断可以用case when的方式操作,如果只替换其中一部分可以用regexp_replace操作。
get_json_object(string json_string,string path)
该函数的第一个参数是json对象变量,第二个参数使用$表示json变量标识,然后用.或[]读取对象或数组。
例如:
如果json为:
Json={"store":{"fruit":\[{"weight":8,"type":"apple"},{"weight":9,"type":"pear"}], "bicycle":{"price":19.95,"color":"red"} }, "email":"amy@only_for_json_udf_test.net", "owner":"amy" }
对应的SQL为:
SELECT get_json_object(json, '$.owner') FROM src_json;--amySELECT get_json_object(json, '$.store.fruit\[0]') FROM src_json;--{"weight":8,"type":"apple"}SELECT get_json_object(json, '$.non_exist_key') FROM src_json;--NULL
第二个常用的函数为:
json_tuple(string json_string,string k1,string k2...)
该函数的第一个参数是json对象变量,之后的参数是不定长参数,是一组键k1,k2...,返回值是元组,该方法比get_json_object高效,因为可以在一次调用中输入多个键值。
select src.timestamp, b.*from src_json srclateral view json_tuple(src.json, 'email', 'owner') b as f1, f2;
另外,单个字符串如果是url,可以直接使用pares_url函数,个人感觉这个函数比较鸡肋,看起来很有用,但是大部分功能可以用string拼接的方式搞定。
URL解析函数:parse_url
语法:
parse_url(string urlString, string partToExtract [, stringkeyToExtract])
返回值: string
说明:返回URL中指定的部分。
partToExtract的有效值为:HOST, PATH, QUERY, REF, PROTOCOL, AUTHORITY, FILE, and USERINFO.
举例:
select parse_url('http://facebook.com/path1/p.php?k1=v1&k2=v2#Ref1', 'HOST') from lxw_dual;--facebook.comselect parse_url('http://facebook.com/path1/p.php?k1=v1&k2=v2#Ref1', 'QUERY','k1')from lxw_dual--v1
应用过程中还有一个k-v值的函数:
str_to_map(String text,String delimiter1,String delimiter2)
使用两个分隔符将文本拆分成键值对。Delimiter1将文本分成k-v对,Delimiter2分割每个k-v对。对于delimiter1的默认值是',',delimiter2的默认值是'='。
select str_to_map('abc:11&bcd:22', '&', ':')--[“abc”:“11”, “bcd”:“22”]
3)多字符串操作:
concat():字符串拼接
concat('aa','bb','cc')=aabbcc
concat_ws(sep,str1,str2,...):根据固定的分隔符连接后侧字符串;
concat_ws第一个参数是其它参数的分隔符,分隔符的位置放在要连接的两个字符串之间,分隔符可以是一个字符串,也可以是其他参数。
Select concat_ws(',','11','22','33'); --11,22,33
split(str,regex):数据切分。
该函数第一个参数是字符串,第二个参数是设定的分隔符,通过第二个参数把第一个参数做拆分,返回一个数组:
select split('123,3455,2568',',')--[“123”,”123”,”123”]
字段的数据处理
特征处理过程中也会经常遇到条件处理,例如:是否为空、满足什么条件、排序等,我们简单做一下了解:
1)是否为空的判断:
select nvl(T v1, T default_value);-- 如果v1不为null返回v1,否则default Value。select nvl(null,0);select coalesce(T v1, T v2, T v3, ...);--返回第一个不为null的value值。select COALESCE(null,'aaa',50)from default.dual limit 1;--aaaselect COALESCE(1,'aaa',50)from default.dual limit 1;--1
2)条件判断:
select if(boolean testCondition, T valueTrue, T valueFalseOrNull);select if(1=1,'bbbb',111);--if条件判断表达式。
3)row_number()函数:分组排序的功能。
row_number() over(distribute by col1 sort by clo2 desc)
字段的行列变化
Hive中比较有特色的功能是行列变化,可以实现多行变一行,也可以实现一行变多行,但是其中有个缺陷,就是多行变多列无法实现,会用python的同学可以通过pyspark实现对应的变化:
1)多行变一行:
collect_list/collect_set列转行函数。
我们看对应的表结构为:
使用collect_list之后为:
仔细看发现“李四”看了两遍“霸王别姬”,需要去重,因此,使用collect_set函数:
这一功能的一个最大好处是突破了group by的限制,分组之后如果另一个字段有多个值且不在分组字段中,则需要用collect_set/collect_list函数。
以上为多行转一行,如何将一行转多行呢?
2)一行转多行:
我们有explode()和lateral view()函数:
explode():
该函数接收一个参数,参数类型需是array或者map类型,该函数的输出是把输入参数的每个元素拆成独立的一行记录。
select explode(split('123,3455,2568',','))
这个函数的一个问题在于无法将list/set等格式做转化,如果要做转化则需要将list/set转化成string,然后再用explode/split切分形成多行。
lateral view():
Lateral View 一般与用户自定义表生成函数(如explode())结合使用。UDTF为每个输入行生成零个或多个输出行,Lateral view首先将UDTF应用于基表的每一行,然后将结果输出行连接到输入行,已形成具有提供的表别名的虚拟表。
例如:
select items_page, numfrom data_limitlateral view explode(items_pages) good as items_page
其中:
a)explode是将items_pages行变列;
b)good是虚拟表,用来存储explode之后的数据,并定义列名为items_page;
c)lateral view是将items_page与上面的字段num进行笛卡尔积,呈现出多列表示;
跳开hive,我们可以通过pyspark实现多行变多列,如下:
data=spark.createDataFrame([[1,[2,9],3],[4,[5,6],6],[7,[8,0],9]],['a','b','c'])Length = len(data.select(‘b’).take(1)[0][0])data_t=data.select([data.b]+[data.b[i] for i in range(length)]).show()Print(data_t)
结果为:
如上即为hive的一些常用函数,笔者做了简单汇总,希望对大家有所助益。
欢迎大家关注公众号:来都来了,点个关注再走呗~
hive substr函数_数据分析工具篇——HQL函数及逻辑相关推荐
- stat函数_数据分析工具入门 掌握这些Excel函数就够了
1.什么是函数 可以把函数理解为一个可以控制的黑箱子,输入X到黑箱子中,他就会输出Y,参数就是黑箱子的控制开关,打到不同的档位,黑箱子会输出不同的Y. 2.常见函数分类 文本清 ...
- 数据分析工具篇——HQL原理及函数逻辑
HQL原理及优化 HQL是数据分析过程中的必备技能,随着数据量增加,这一技能越来越重要,熟练应用的同时会带来效率的问题,动辄十几亿的数据量如果处理不完善的话有可能导致一个作业运行几个小时,更严重的还有 ...
- subtotal函数_用SUBTOTAL更改Excel函数
subtotal函数 We looked at the Excel SUBTOTAL function on Friday, and saw how it works with hidden rows ...
- hive 日期函数_数据分析面试必备——SQL窗口函数你会了吗?
之前写过一篇sql的文章,面向基础的sql操作(无眠:数据分析面试必备--SQL你准备好了吗?),目前已经有12000+收藏(收藏是点赞的5倍,你们可真狠心哪),也可以看出众多同学对sql学习的热情. ...
- 谁说菜鸟不会数据分析python篇下载_谁说菜鸟不会数据分析(工具篇) 张文霖 中文PDF影印版[36.4MB]...
谁说菜鸟不会数据分析(工具篇)张文霖 中文PDF影印版[36.4MB] 作者: 张文霖 等 图书分类: 软件 资源格式: PDF 版本: 影印版 出版社: 电子工业出版社 书号: 9787121204 ...
- hive编程指南_第三篇|Spark SQL编程指南
在<第二篇|Spark Core编程指南>一文中,对Spark的核心模块进行了讲解.本文将讨论Spark的另外一个重要模块--Spark SQL,Spark SQL是在Shark的基础之上 ...
- python医学应用_数据分析工具鄙视链:Python、R语言是老大,Excel只能称小弟?
最新行业报告 2020数据分析.商业分析行业报告工作岗位与职能.薪资对比.热招公司等多方面详细解读帮助你一网打尽,斩获心仪Offer! 扫码回复[数据分析 0]立即领取 History语言发展史ABC ...
- ltrim函数_数据分析常用Excel函数
Excel是我们工作中经常使用的一种工具,对于数据分析来说,这也是处理数据最基础的工具.本文介绍数据分析中最常用的Excel函数. 查找匹配类 文本数据清洗类 日期类 逻辑运算类 计算统计类 一.查找 ...
- bi工具选型_数据分析工具:选合适了,分析也能事半功倍
前言 哪款分析工具比较适合企业做分析?如果企业没有深入了解可能会被市面上漫天的产品广告所淹没,毕竟广告上写的都是可直接对接某某ERP系统的宣言,但深究发现其实背后可能还隐藏了一层:依靠IT工作者写代码 ...
最新文章
- python3.6爬虫环境安装要多少内存_Python3爬虫环境配置——解析库安装(附tesserocr安装方法)...
- C/C++产生随机数
- free5GC — 部署端到端 5G 实验网络
- 7.5 程序示例--PCA for 数据可视化-机器学习笔记-斯坦福吴恩达教授
- Redis分布式锁,看完不懂你打我
- doublevalue_Java Double类doubleValue()方法与示例
- Redis高频面试笔记:java版本号比较算法
- Vue Axios的配置 (高仿饿了么)
- linux input子系统分析--主要函数
- 中国男足孔已己版(转载,博大家一笑)
- 【JavaScript】打印星型金字塔
- mybatis一对多关系多表查询去重,不定条件查询,duplicated column id
- C++ int 转字符串
- 学习linux第二十五天
- Lanczos方法计算严格对角化格林函数
- MySQL8.0.27版本于2021年10月19日正式GA和新功能介绍
- ubuntu 安装openssl-devel
- 【2023-03-07】携程春招笔试四道编程题
- shell jq 解析json包含点的key
- HBase 和 RDBMS 相比有什么区别?