「Hive進(jìn)階篇」HiveQL 高級(jí)巧用
數(shù)據(jù)脫敏函數(shù)hive有專門的脫敏函數(shù)供我們使用,就是mask()函數(shù),返回值是string類型,默認(rèn)需要脫敏的數(shù)據(jù)中大寫字母就自動(dòng)轉(zhuǎn)換為X,小寫字母就自動(dòng)轉(zhuǎn)換為x,數(shù)字就自動(dòng)轉(zhuǎn)換為n,也可通過mask()函數(shù)的參數(shù)來自定義轉(zhuǎn)換格式。注意:入?yún)⒁脖仨毷莝tring類型才不會(huì)有隱藏bug
select mask(要加密字段) from 表名 -- 輸出默認(rèn)脫敏后的結(jié)果
select mask(要加密字段,'X','x','#') from 表名 -- 輸出自定義脫敏后的結(jié)果
select mask_first_n(要加密的字段,n) from 表名 -- 對(duì)前n個(gè)字符進(jìn)行脫敏
select mask_last_n(要加密的字段,n) from 表名 -- 對(duì)后n個(gè)字符進(jìn)行脫敏
select mask_show_first_n(要加密的字段,n) from 表名 -- 對(duì)除了前n個(gè)字符之外的字符進(jìn)行脫敏
select mask_show_last_n(要加密的字段,n) from 表名 -- 對(duì)除了后n個(gè)字符之外的字符進(jìn)行脫敏
select mask_hash(字段) from 表名 -- 對(duì)字段進(jìn)行hash操作,若是非string類型的字段此函數(shù)就返回null
hive 獲取當(dāng)天時(shí)間
-- PS:hive3版本對(duì)時(shí)間函數(shù)`unix_timestamp()`和`from_unixtime()`做了重寫,需要加8小時(shí)或者減8小時(shí),結(jié)果才正確
select current_date -- 2022-06-19
select from_unixtime(unix_timestamp() + 8*3600) -- 2022-06-19 15:30:54
hive 格式化時(shí)間數(shù)據(jù)
select from_unixtime(unix_timestamp() + 8*3600,'yyyy-MM') -- 2022-06
select date_format(from_unixtime(unix_timestamp()),'yyyy-MM') -- 2022-06
hive 獲取本月第一天,本年第一天,上個(gè)月第一天,本月最后一天,下個(gè)月第一天等指標(biāo)
select trunc(from_unixtime(unix_timestamp() + 8*3600),'MM') -- 2022-06-01
select trunc(from_unixtime(unix_timestamp() + 8*3600),'YEAR'); -- 2022-01-01
select trunc(add_months(from_unixtime(unix_timestamp() + 8*3600),-1),'MM') -- 2022-05-01
select last_day(from_unixtime(unix_timestamp() + 8*3600)) -- 2022-06-30
select trunc(add_months(from_unixtime(unix_timestamp() + 8*3600),1),'MM') -- 2022-07-01
datediff日期比較函數(shù)第一個(gè)參數(shù)是結(jié)束日期,第二個(gè)是開始日期,返回結(jié)束日期減開始日期
select datediff('2020-07-05','2020-06-15'); -- 返回20,注意日期格式認(rèn)準(zhǔn)- ,如果是/則無效,得使用格式轉(zhuǎn)換
hive對(duì)yyyy/MM/dd格式的日期和yyyy-MM-dd格式的日期相互轉(zhuǎn)換方案
第一種是通過from_unixtime()+unix_timestamp()轉(zhuǎn)換時(shí)間戳方式轉(zhuǎn)換
第二種是通過concat()+substr()拼接截取方式轉(zhuǎn)換,
第三種是通過regexp_replace()正則匹配方式去掉橫杠。
select
'2022/08/09' as source_text
,from_unixtime(unix_timestamp('2022/08/09','yyyy/MM/dd'),'yyyy-MM-dd') as func_text_1 -- 方案一
,concat(substr('2022/08/09',1,4),'-',substr('2022/08/09',6,2),'-',substr('2022/08/09',9,2)) as func_text_2 -- 方案二
,regexp_replace('2022/08/09','/','-') as func_text_3 -- 方案三
hive的多行轉(zhuǎn)多列
方案一:利用拼接的方式構(gòu)造map類型
方案二:利用if判斷表達(dá)式+聚合收斂
-- 方案一,利用拼接的方式構(gòu)造map類型
select stat_date
,event_list['test1'] as test1_cnt
,event_list['test2'] as test2_cnt
from
(
select
stat_date
,str_to_map(concat_ws(',',collect_list(concat_ws(':',event_name,cast(event_cnt as string))))) as event_list
from
(
select
stat_date
,event_name
,count(1) as event_cnt
from 表名
where stat_date between 20220801 and 20220810
and event_name in('test1','test2')
group by stat_date
,event_name
) s
group by stat_date
) w
-- 方案二,利用if判斷表達(dá)式
select
stat_date
,sum(if(event_name='test1',event_cnt,0)) as test1_cnt
,sum(if(event_name='test2',event_cnt,0)) as test2_cnt
from
(
select
stat_date
,event_name
,count(1) as event_cnt
from 表名
where stat_date between 20220801 and 20220810
and event_name in('test1','test2')
group by stat_date
,event_name
) s
group by stat_date
hive查找數(shù)組內(nèi)是否包含某個(gè)元素select array_contains(array<int>,某元素); 注意:array_contains()函數(shù)支持int數(shù)組或者string數(shù)組,不支持bigint數(shù)據(jù)類型的數(shù)組。
hive字符串?dāng)?shù)組類型的數(shù)據(jù)轉(zhuǎn)為字符串?dāng)?shù)據(jù)select concat_ws(',',array<string>);
hive的空處理函數(shù),coalesce(數(shù)據(jù)字段,'自定義值')select coalesce(aaa,'空值清洗')
select mask(要加密字段) from 表名 -- 輸出默認(rèn)脫敏后的結(jié)果
select mask(要加密字段,'X','x','#') from 表名 -- 輸出自定義脫敏后的結(jié)果
select mask_first_n(要加密的字段,n) from 表名 -- 對(duì)前n個(gè)字符進(jìn)行脫敏
select mask_last_n(要加密的字段,n) from 表名 -- 對(duì)后n個(gè)字符進(jìn)行脫敏
select mask_show_first_n(要加密的字段,n) from 表名 -- 對(duì)除了前n個(gè)字符之外的字符進(jìn)行脫敏
select mask_show_last_n(要加密的字段,n) from 表名 -- 對(duì)除了后n個(gè)字符之外的字符進(jìn)行脫敏
select mask_hash(字段) from 表名 -- 對(duì)字段進(jìn)行hash操作,若是非string類型的字段此函數(shù)就返回null
hive 獲取當(dāng)天時(shí)間
-- PS:hive3版本對(duì)時(shí)間函數(shù)`unix_timestamp()`和`from_unixtime()`做了重寫,需要加8小時(shí)或者減8小時(shí),結(jié)果才正確
select current_date -- 2022-06-19
select from_unixtime(unix_timestamp() + 8*3600) -- 2022-06-19 15:30:54
hive 格式化時(shí)間數(shù)據(jù)
select from_unixtime(unix_timestamp() + 8*3600,'yyyy-MM') -- 2022-06
select date_format(from_unixtime(unix_timestamp()),'yyyy-MM') -- 2022-06
hive 獲取本月第一天,本年第一天,上個(gè)月第一天,本月最后一天,下個(gè)月第一天等指標(biāo)
select trunc(from_unixtime(unix_timestamp() + 8*3600),'MM') -- 2022-06-01
select trunc(from_unixtime(unix_timestamp() + 8*3600),'YEAR'); -- 2022-01-01
select trunc(add_months(from_unixtime(unix_timestamp() + 8*3600),-1),'MM') -- 2022-05-01
select last_day(from_unixtime(unix_timestamp() + 8*3600)) -- 2022-06-30
select trunc(add_months(from_unixtime(unix_timestamp() + 8*3600),1),'MM') -- 2022-07-01
datediff日期比較函數(shù)第一個(gè)參數(shù)是結(jié)束日期,第二個(gè)是開始日期,返回結(jié)束日期減開始日期
select datediff('2020-07-05','2020-06-15'); -- 返回20,注意日期格式認(rèn)準(zhǔn)- ,如果是/則無效,得使用格式轉(zhuǎn)換
hive對(duì)yyyy/MM/dd格式的日期和yyyy-MM-dd格式的日期相互轉(zhuǎn)換方案
第一種是通過from_unixtime()+unix_timestamp()轉(zhuǎn)換時(shí)間戳方式轉(zhuǎn)換
第二種是通過concat()+substr()拼接截取方式轉(zhuǎn)換,
第三種是通過regexp_replace()正則匹配方式去掉橫杠。
select
'2022/08/09' as source_text
,from_unixtime(unix_timestamp('2022/08/09','yyyy/MM/dd'),'yyyy-MM-dd') as func_text_1 -- 方案一
,concat(substr('2022/08/09',1,4),'-',substr('2022/08/09',6,2),'-',substr('2022/08/09',9,2)) as func_text_2 -- 方案二
,regexp_replace('2022/08/09','/','-') as func_text_3 -- 方案三
hive的多行轉(zhuǎn)多列
方案一:利用拼接的方式構(gòu)造map類型
方案二:利用if判斷表達(dá)式+聚合收斂
-- 方案一,利用拼接的方式構(gòu)造map類型
select stat_date
,event_list['test1'] as test1_cnt
,event_list['test2'] as test2_cnt
from
(
select
stat_date
,str_to_map(concat_ws(',',collect_list(concat_ws(':',event_name,cast(event_cnt as string))))) as event_list
from
(
select
stat_date
,event_name
,count(1) as event_cnt
from 表名
where stat_date between 20220801 and 20220810
and event_name in('test1','test2')
group by stat_date
,event_name
) s
group by stat_date
) w
-- 方案二,利用if判斷表達(dá)式
select
stat_date
,sum(if(event_name='test1',event_cnt,0)) as test1_cnt
,sum(if(event_name='test2',event_cnt,0)) as test2_cnt
from
(
select
stat_date
,event_name
,count(1) as event_cnt
from 表名
where stat_date between 20220801 and 20220810
and event_name in('test1','test2')
group by stat_date
,event_name
) s
group by stat_date
hive查找數(shù)組內(nèi)是否包含某個(gè)元素select array_contains(array<int>,某元素); 注意:array_contains()函數(shù)支持int數(shù)組或者string數(shù)組,不支持bigint數(shù)據(jù)類型的數(shù)組。
hive字符串?dāng)?shù)組類型的數(shù)據(jù)轉(zhuǎn)為字符串?dāng)?shù)據(jù)select concat_ws(',',array<string>);
hive的空處理函數(shù),coalesce(數(shù)據(jù)字段,'自定義值')select coalesce(aaa,'空值清洗')
作者:bigdataladder
歡迎關(guān)注微信公眾號(hào) :大數(shù)據(jù)階梯之路