Hive【Hive(五)函数-高级聚合函数、炸裂函数】

高级聚合函数

多进一出(多行输入,一个输出)

普通聚合函数:count、sum ...

1)collect_list():收集并形成 list 集合,结果不去重

select sex,collect_list(job)
from employee
group by sex;
--女	["行政","研发","行政","前台"]
--男	["销售","研发","销售","前台"]

2)collect_set():收集并形成 set 集合,结果去重

select sex,collect_set(job)
from employee
group by sex;
--女	["行政","研发","前台"]
--男	["销售","研发","前台"]

案例

1)每个月的入职人数以及姓名
select month(replace(hire_date,'/','-')) as month,
       count(*) cnt,
       collect_list(name) as name_list
from employee
group by month(replace(hire_date,'/','-'));

运行结果: 

month  cnt  name_list
4	    2	["宋青书","周芷若"]
6	    1	["黄蓉"]
7	    1	["郭靖"]
8	    2	["张无忌","杨过"]
9	    2	["赵敏","小龙女"]

炸裂函数(UDTF)

接受一行数据,输出一行或多行数据。

TF(Table-Genrating Functions),表生成函数,也就是说这个函数的结果是一张表。

1、常用 UDTF - explode(array<T> a)

explode(array<T> a)接受一个数组类型的参数,它会把这一个数组炸裂成一个列(多行)。

语法
select explode(array("a","b","c"))as item;
-- item
-- a
-- b
-- c

2、 常用 UDTF - explode(Map<K,V> m)

返回多行2列(key,value)。

语法

注意:不加别名时,它默认的字段也是 key 和 value,我们自定义多个字段名时需要加括号。

select explode(map('hadoop','1','spark',2)) as (key,value);
-- key  value
-- hadoop 1
-- spark 2

 3、常用 UDTF - posexplode(array<T> a)

接受一个数组 array ,pos 的意思是 position ,也就是数组的下标。它返回多行两列,一列为 pos(索引) ,一列是 val(值)。

select posexplode(array('a','b','c'));
-- pos val
-- 0    a
-- 1    b
-- 2    c

4、常用 UDTF - inline(array<struct<f1:T1,...,fn:Tn>> a)

它接受一个 结构体数组 ,返回多行多列,列数=结构体的属性数量。

注意:每个结构体的属性数量必须一致。

select inline(array(
    named_struct("id",1,"name","zs","age",15),
    named_struct("id",2,"name","ls","age",17),
    named_struct("id",3,"name","ww","age",23)
    )) as (id,name,age);

运行结果: 

Lateral View(常用)

Lateral View 通常与UDTF 配合使用。它可以将UDTF应用到源表的每行数据,UDTF会将每行数据转换为一行或多行,Lateral View会将源表中每行的输出结果与该行连接起来,形成一个虚拟表。

数据准备
create table movie_info(
    movie string,     --电影名称
    category string   --电影分类
)
row format delimited fields terminated by "\t";

insert overwrite table movie_info
values ("《疑犯追踪》", "悬疑,动作,科幻,剧情"),
       ("《Lie to me》", "悬疑,警匪,动作,心理,剧情"),
       ("《战狼2》", "战争,动作,灾难");
函数演示
select
    movie,
    category_name
from
movie_info
lateral view
explode(split(category,",")) movie_info_tmp as category_name;

运行结果:

select cate,count(*)
from (
    select movie,cate
    from (
        select movie,
            split(category,',') cates
        from movie_info
         )t1 lateral view explode(cates) tmp as cate
)t2
group by cate;

运行结果:

窗口函数

明天写

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
spark + hive 自定义聚合函数回顾--group_concat实现 group_concat是一种常用的聚合函数,它可以将同一组内的多个值合并成一个字符串。在hive中,group_concat函数已经内置,但是在spark中需要自定义实现。 实现group_concat函数的步骤如下: 1. 继承org.apache.spark.sql.expressions.UserDefinedAggregateFunction类,实现其抽象方法。 2. 定义输入和输出的数据类型。 3. 实现update方法,用于更新聚合结果。 4. 实现merge方法,用于合并不同分区的聚合结果。 5. 实现evaluate方法,用于输出最终的聚合结果。 下面是一个简单的group_concat实现示例: import org.apache.spark.sql.expressions.{MutableAggregationBuffer, UserDefinedAggregateFunction} import org.apache.spark.sql.types.{DataType, StringType, StructType} import org.apache.spark.sql.{Row, SparkSession} class GroupConcat extends UserDefinedAggregateFunction { // 定义输入数据类型 def inputSchema: StructType = new StructType().add("value", StringType) // 定义中间缓存数据类型 def bufferSchema: StructType = new StructType().add("buffer", StringType) // 定义输出数据类型 def dataType: DataType = StringType // 定义是否是确定性的 def deterministic: Boolean = true // 初始化中间缓存数据 def initialize(buffer: MutableAggregationBuffer): Unit = { buffer.update(0, "") } // 更新中间缓存数据 def update(buffer: MutableAggregationBuffer, input: Row): Unit = { val str = input.getString(0) if (!buffer.isNullAt(0)) { buffer.update(0, buffer.getString(0) + "," + str) } else { buffer.update(0, str) } } // 合并不同分区的中间缓存数据 def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = { if (!buffer2.isNullAt(0)) { update(buffer1, buffer2) } } // 输出最终的聚合结果 def evaluate(buffer: Row): Any = { buffer.getString(0) } } // 使用示例 val spark = SparkSession.builder().appName("group_concat").master("local[*]").getOrCreate() spark.udf.register("group_concat", new GroupConcat) val df = spark.sql("select id, group_concat(name) as names from table group by id") df.show() 在使用时,需要先将自定义的聚合函数注册到spark中,然后就可以在sql中使用了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

让线程再跑一会

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

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

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

打赏作者

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

抵扣说明:

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

余额充值