Hive SQL 函数高阶应用场景

HIVE作为数据仓库处理常用工具,如同RDBMS关系型数据库中标准SQL语法一样,Hive SQL也内置了不少系统函数,满足于用户在不同场景下的数据分析需求,以提高开发SQL数据分析的效率。
我们可以使用show functions查看当下版本支持的函数,并且可以通过describe function extended funcname来查看函数对应的使用方式和方法,下面我们将描述HIVE SQL中常用函数的高阶使用场景。

1、行转列(explode)

如下活动列表:tb_activities

活动ID活动名称列表
1001双111,国庆,元旦
2001黄金周,国庆,元旦

希望转换为列类型活动表:tb_activitity

活动ID活动名称
1001双11
1001国庆
1001元旦
2001黄金周
2001国庆
2001元旦

使用到Hive内置一个非常著名的UDTF函数,名字叫做explode函数,中文戏称为“爆炸函数”,可以炸开数据转换为多行。

select act_id,activity from tb_activities 
lateral view explode(split(activities,','))enum_tmp as activity;

扩展: 如果要按照活动Id增加索引,可以使用posexplode:

编号活动ID活动名称
11001双11
21001国庆
31001元旦
12001黄金周
22001国庆
32001元旦
select pos+1,act_id,activity from tb_activities 
lateral view explode(split(activities,','))enum_tmp as pos,activity

2、列转行

如上1所示,希望从tb_activity转换为tb_activities,通过collect_set()方法和group by act_id 将列转换为行,实现如下:

 select act_id, concat_ws(',',collect_set(activity)) as activities 
 from tb_activity group by act_id;

3、排名(rank())

可以通过rank() 方法的使用,实现对指定列进行排名,输出排名结果。例如商品总数表:t_item_sum,需要实现排名功能:

item_iditem_sum
100120
100212
100362
100415

期望得到:

item_iditem_sumrank
1003621
1001202
1004153
1002124

代码实现如下:

select item_id,item_sum,rank()over(order by item_sum desc) as rank from t_item_sum;

4、分组去重

在查询数据时如果有重复,我们可以使用用distinct 去除重复值,但使用 distinct 只能去除所有查询列都相同的记录,如果某个字段不同,distinct 就无法去重。这时我们可以用 row_number()over(partitioon by column1 order by column2) 先进行分组。
例如:有活动表数据列“活动id,用户id,活动名称,客户群组,过期时间”,希望按照”活动id,活动名称,客户群组”去重,取最新一条数据。

iduser_idactivitycust_groupexpired_at
BCP0151001春节活动A高价值2023-10-05
BCP0151001春节活动A高价值2023-10-15
BCP0151001春节活动A高价值2023-10-28
BCP0251002春节活动B中价值2023-10-05
BCP0251002春节活动B中价值2023-10-25
BCP0301003春节活动C中价值2023-10-25

期望得到:

iduser_idactivitycust_groupexpired_at
BCP0151001春节活动A高价值2023-10-28
BCP0251002春节活动B中价值2023-10-25
BCP0301003春节活动C中价值2023-10-25

使用row_number()over(partitioon by) 分组去重。

  select tt1.* from(select id, user_id, activity,cust_group,
  row_number() over(partition by concat(id,activity,cust_group)
  order by expired_at desc)as row_num 
  from tb_acitivity_full)tt1 where tt1.row_num=1;

5、指标统计

GROUPING SETS,GROUPING__ID,CUBE,ROLLUP,这几个hive分析函数通常用于OLAP中,不能累加,而且需要根据不同维度上钻( roll up )和下钻( drill down )的指标统计,比如,分小时、天、月的UV数。上钻是沿着维度的层次向上聚集汇总数据,下钻是在分析时加深维度,对数据进行层层深入的查看。通过逐层下钻,数据更加一目了然,更能充分挖掘数据背后的价值,及时做出更加正确的决策。

OLAP函数使用说明
GROUPING SETS根据不同的维度组合进行聚合,等价于将不同维度的GROUP BY结果集进行UNION ALL
GROUPING__ID表示结果属于哪一个分组集合,属于虚字段
CUBE可根据GROUP BY的维度的所有组合进行聚合
ROLLUP作为CUBE的子集,以最左侧的维度为主,从该维度进行层级聚合

如4所示,希望对指标值进行统计,期望结果:

indicatorenum_valuecount
idBCP0153
idBCP0252
idBCP0301
activity春节活动A3
activity春节活动B2
activity春节活动C1
cust_group高价值3
cust_group中价值3

通过grouping__id 内层SQL处理结果,表2:

groupIdidactivitycust_groupuv
1728id_BCP015NULLNULL3
1724id_BCP025NULLNULL2
1723id_BCP030NULLNULL1
2728NULLactivity_春节活动ANULL3
2724NULLactivity_春节活动BNULL2
2723NULLactivity_春节活动CNULL1
3723NULLNULLcust_group_高价值3
3724NULLNULLcust_group_中价值3
select 
  split(coalesce(
   id,
   activity,
   cust_group),'\\_')[0] as indicator,
  coalesce(
   split(id, '\\_')[1],
   split(activity, '\\_')[1],
   split(cust_group, '\\_')[1],
  ) as enum_value
  sum(uv) as count
  from (
  -- 内层SQL处理结果,对应上表2
   select grouping__id as groupId,
    concat('id|',id) as id,
    concat('activity|', activity) as activity,
    concat('cust_group|',cust_group) as cust_group,
    count(*) as uv
   from tb_acitivity_full
   group by 
    concat('id|',id),
    concat('activity|', activity),
    concat('cust_group|',cust_group)
   grouping sets(
    concat('id|',id),
    concat('activity|', activity),
    concat('cust_group|',cust_group)
  )as tt1
  group by split(coalesce(
   id,
   activity,
   cust_group),'\\_')[0],
  coalesce(
   split(id, '\\_')[1],
   split(activity, '\\_')[1],
   split(cust_group, '\\_')[1],
  );

6、JSON数据处理

JSON数据作为数据存储和数据处理中最常见的结构化数据格式之一,许多场景下都会将数据以JSON格式存储在文件系统(HDFS/MINIO等)中,当构建数据仓库时,对JSON格式的数据进行处理和分析,就需要在Hive中使用对应函数对JSON格式的数据进行解析读取。
例如,JSON格式的数据如下:

商品ID商品名称额外信息
1001IP15“fixedIntegral”:200, “source”:“wechat”,“stages”:12}

获取商品可使用的固定积分:

select get_json_object(extra_json, '$fixedIntegral) as integral
from t_items;

7、替换

7.1 translate 函数用法
select translate('abcdef', 'adc', '19') tb_translate_exe
输出:
1b9ef
  • translate(input,from,to)
  • input:输入字符串
  • from:需要匹配的字符
  • to :用哪些字符来替换被匹配到的字符
    注意点:这里from的字符与to字符在位置上存在一 一对应关系,也就是from中每个位置上的字符用to中对应位置的字符替换。
7.1 regexp_replace 函数

正则替换

SELECT  aa
        ,REGEXP_REPLACE(aa, '[a-z]', '')    -- 替换所有字母
        ,REGEXP_REPLACE(aa, '[abc]', '')    -- 替换指定字母
        ,REGEXP_REPLACE(aa, '[^abc]', '')    -- 替换所有非字母
        ,REGEXP_REPLACE(aa, '[0-9]', '')    -- 替换所有数字
        ,REGEXP_REPLACE(aa, '[\\s\\S]', '')    -- 替换空白符、换行,\\s:是匹配所有空白符,包括换行,\\S:非空白符,不包括换行。
        ,REGEXP_REPLACE(aa, '\\w', '')    -- 替换所有字母、数字、下划线。等价于 [A-Za-z0-9_]
        ,REGEXP_REPLACE(aa, '[-8+]', '')    -- 只替换-8这个字符
        ,REGEXP_REPLACE(aa, '[-8*]', '')    -- 替换-8、-、8这几个字符
FROM    (
            SELECT  '5e40b2b8-0916-42c0-899a-eaf4b2df 5268' AS aa
            UNION ALL
            SELECT  'c81b5906-38d7-482c-8b66-be5d3359cbf6' AS aa
            UNION ALL
            SELECT  '8856fd0a-2337-4605-963f-0d0d059b1937' AS aa
        ) t
;
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Moutai码哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值