Hive SQL 函数高阶应用场景

HIVE作为数据仓库处理常用工具,如同RDBMS关系型数据库中标准SQL语法一样,Hive SQL也内置了不少系统函数,满足于用户在不同场景下的数据分析需求,以提高开发SQL数据分析的效率。

我们可以使用show functions查看当下版本支持的函数,并且可以通过describe function extended funcname来查看函数对应的使用方式和方法,下面我们将描述HIVE SQL中常用函数的高阶使用场景。

1、行转列(explode)

如下活动列表:tb_activities

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

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

活动ID 活动名称
1 双11
1 国庆
1 元旦
2 黄金周
2 国庆
2 元旦

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

sql 复制代码
insert into table tb_activitity select id,activity from tb_activities 
lateral view explode(split(activities,','))enum_tmp as activity;

2、列转行

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

sql 复制代码
 select id, concat_ws(',',collect_set(activity)) as activities 
 from tb_activity group by id;

3、排名(rank())

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

item_id item_sum
1001 20
1002 12
1003 62
1004 15

期望得到:

item_id item_sum rank
1003 62 1
1001 20 2
1004 15 3
1002 12 4

代码实现如下:

sql 复制代码
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,活动名称,客户群组"去重,取最新一条数据。

id user_id activity cust_group expired_at
BCP015 1001 春节活动A 高价值 2023-10-05
BCP015 1001 春节活动A 高价值 2023-10-15
BCP015 1001 春节活动A 高价值 2023-10-28
BCP025 1002 春节活动B 中价值 2023-10-05
BCP025 1002 春节活动B 中价值 2023-10-25
BCP030 1003 春节活动C 中价值 2023-10-25

期望得到:

id user_id activity cust_group expired_at
BCP015 1001 春节活动A 高价值 2023-10-28
BCP025 1002 春节活动B 中价值 2023-10-25
BCP030 1003 春节活动C 中价值 2023-10-25

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

sql 复制代码
  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所示,希望对指标值进行统计,期望结果:

indicator enum_value count
id BCP015 3
id BCP025 2
id BCP030 1
activity 春节活动A 3
activity 春节活动B 2
activity 春节活动C 1
cust_group 高价值 3
cust_group 中价值 3

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

groupId id activity cust_group uv
1728 id_BCP015 NULL NULL 3
1724 id_BCP025 NULL NULL 2
1723 id_BCP030 NULL NULL 1
2728 NULL activity_春节活动A NULL 3
2724 NULL activity_春节活动B NULL 2
2723 NULL activity_春节活动C NULL 1
3723 NULL NULL cust_group_高价值 3
3724 NULL NULL cust_group_中价值 3
sql 复制代码
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 商品名称 额外信息
1001 IP15 "fixedIntegral":200, "source":"wechat","stages":12}

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

sql 复制代码
select get_json_object(extra_json, '$fixedIntegral) as integral
from t_items;

7、替换

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

正则替换

sql 复制代码
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
;
相关推荐
麦聪聊数据18 小时前
MySQL 性能调优:从EXPLAIN到JSON索引优化
数据库·sql·mysql·安全·json
yumgpkpm19 小时前
AI评判:信创替代对Cloudera CDH CDP Hadoop大数据平台有何影响?
大数据·hive·oracle·flink·kafka·hbase·cloudera
小四的快乐生活19 小时前
大数据SQL诊断(采集、分析、优化方案)
大数据·数据库·sql
l1t20 小时前
DeepSeek辅助编写的利用唯一可选数求解数独SQL
数据库·sql·算法·postgresql
樱花味的小奶牛21 小时前
DECLARE CURSOR 才允许使用 FOR UPDATE 子句
数据库·sql
问今域中21 小时前
Spring Security登录认证
数据库·sql·oracle
sheji34161 天前
【开题答辩全过程】以 基于Hadoop教育平台的设计与实现为例,包含答辩的问题和答案
大数据·hadoop·分布式
Gauss松鼠会1 天前
【GaussDB】从 sqlplus 到 gsql:Shell 中执行 SQL 文件方案的迁移与改造
数据库·sql·database·gaussdb
MindCareers1 天前
Beta Sprint Day 5-6: Android Development Improvement + UI Fixes
android·c++·git·sql·ui·visual studio·sprint
yumgpkpm1 天前
Cloudera CDH5、CDH6、CDP7现状及替代方案
数据库·人工智能·hive·hadoop·elasticsearch·数据挖掘·kafka