Hive自定义函数返回两个日期间的月份


需求:现有一张用户信息表,记录用户会员信息

在这里插入图片描述
现在需要统计每个月的有效会员数量

问题分析: 想要统计每个月份的有效会员数量就要获取表中所有存在的月份,有两种思路:

第一种可以直接一点:

直接根据表数据创建一个临时辅助表 (有点low但简单)

insert into MonthTable
select concat(year, '-', lpad(month, 2, '0')) as month_year
from (
select 2021 as year, 1 as month union all
select 2021, 2 union all
select 2021, 3 union all
select 2021, 4 union all
select 2021, 5 union all
select 2021, 6 union all
select 2021, 7 union all
select 2021, 8 union all
select 2021, 9 union all
select 2021, 10 union all
select 2021, 11 union all
select 2021, 12 union all
select 2022, 1 union all
select 2022, 2 union all
select 2022, 3 union all
select 2022, 4 union all
select 2022, 5 union all
select 2022, 6 union all
select 2022, 7 union all
select 2022, 8 union all
select 2022, 9 union all
select 2022, 10 union all
select 2022, 11 union all
select 2022, 12
) as year_month;

然后可以和原表进行表连接进行查询:

select
m.month_year,
count(c.consumerid) as active_members
from
MonthTable m
left join
t_consumer c
on
m.month_year between date_format(c.startdate, 'yyyy-MM') and date_format(c.enddate, 'yyyy-MM')
group by
m.month_year
order by
m.month_year;

第二种是采用自定义函数(注:这里只书写了关键操作

利用 Java 的 UDTF 类来自定义一个函数用于返回两个日期之间的月份:

public class VipCountUDTF extends GenericUDTF {
    @Override
    public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
        // 返回值的数据类型和名称
        //1.定义输出数据的列名和类型
        List<String> fieldNames = new ArrayList<String>();
        List<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();
        //2.添加输出数据的列名和类型
        fieldNames.add("mt");
        fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
        return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);
    }
    @Override
    public void process(Object[] objects) throws HiveException {
        String beginDate = objects[0].toString();
        String endDate = objects[1].toString();
        // 调用之前的方法,返回一个日期列表
        List<String> dateList = DateUtils.getDateList(beginDate, endDate);
        for(String date : dateList)
        {
            forward(new String[]{date});
        }
    }
    @Override
    public void close() throws HiveException {
    }
}
 class DateUtils {
    public static List<String> getDateList(String beginDate, String endDate) {
        ArrayList<String> list = new ArrayList<>();
        // 解析传递过来的日期的格式
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM");
        // 将Date类型转换为字符串类型,前面是月份,后面是年份
        SimpleDateFormat sdf = new SimpleDateFormat("MMM-yyyy", Locale.ENGLISH);
        try {
            // 将传递过来的日期转换为Date类型
            Date dateFrom = simpleDateFormat.parse(beginDate);
            Date dateTo = simpleDateFormat.parse(endDate);
            // 因为需要用到Calendar 中的 获取下一个月的日期的函数
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(dateFrom);
            // 判断结束日期是否大于开始日期
            while (dateTo.after(calendar.getTime())) {
                // 将一个日期转为  月份-年份
                String yearMonth = sdf.format(calendar.getTime());
                System.out.println(yearMonth);
                list.add(yearMonth);
                calendar.add(Calendar.MONTH,1);
            }
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        return list;
    }
}

自定义 hive 函数之后把自定义函数上传到 hive 中就可以继续进行操作了:

select mt,count(*) c1
from(
  select consumerid,mt from t_consumer lateral view k1(startdate,enddate) t1 as mt
)t2 group by mt
### 回答1: Hive是一个基于Hadoop数据仓库工具,它提供了动态分区、Bucketing、压缩等高级特性,能够方便地支持大规模的数据仓库查询和分析。 Hive中的自定义函数(UDF)是扩展Hive功能的一种方法,它允许用户自定义自己的函数来处理Hive中的数据。下面我们来介绍一下Hive自定义函数的示例(demo)。 首先,我们需要在Hive中创建一个自定义函数。创建自定义函数的步骤如下: 1. 编写Java代码来实现自定义函数的逻辑。例如,我们可以编写一个函数计算字符串的长度。 ``` package com.example; import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.io.Text; public class StringLengthUDF extends UDF { public int evaluate(Text str) { if (str == null) { return 0; } return str.toString().length(); } } ``` 2. 将Java代码编译为Jar文件,并将其上传到Hive所在的服务器上。 3. 在Hive中创建一个函数,指定函数的名称和Jar文件的路径。 ``` CREATE FUNCTION string_length AS 'com.example.StringLengthUDF' USING JAR 'hdfs://path/to/jar/file.jar'; ``` 现在我们已经成功地创建了一个自定义函数。我们可以在Hive中使用这个函数来处理数据。 例如,我们可以使用这个自定义函数计算字符串的长度: ``` SELECT name, string_length(description) AS length FROM my_table; ``` 以上示例中,我们调用了自定义函数"string_length"来计算"my_table"表中"description"列的长度,并将结果别名为"length"。 通过自定义函数,我们可以方便地实现各种复杂的数据处理逻辑,从而更加灵活和高效地使用Hive进行数据分析。 ### 回答2: Hive是一个基于Hadoop数据仓库工具,它提供了一个SQL接口来查询和分析大规模数据。Hive支持自定义函数以满足特定业务需求。 编写Hive自定义函数的示例,步骤如下: 1. 创建一个Java类,命名为CustomFunction,该类需要继承Hive UDF(User Defined Function)基类。 2. 实现Hive UDF需要重写evaluate方法,该方法用于处理输入参数并返回计算结果。例如,我们可以实现一个自定义函数计算两个整数之和: ``` import org.apache.hadoop.hive.ql.exec.UDF; public class CustomFunction extends UDF { public int evaluate(int a, int b) { return a + b; } } ``` 3. 使用Maven或其他构建工具将Java类打包成JAR文件。 4. 将JAR文件上传到Hive所在的机器上(例如Hadoop集群的某个节点)。 5. 在Hive中加载自定义函数: ``` ADD JAR /path/to/CustomFunction.jar; CREATE TEMPORARY FUNCTION custom_sum AS 'com.example.CustomFunction'; ``` 这里的`/path/to/CustomFunction.jar`是JAR文件的路径,`com.example.CustomFunction`是自定义函数的包和类名。 6. 使用自定义函数进行计算: ``` SELECT custom_sum(2, 3); ``` 这将返回计算结果,即5。 通过编写自定义函数,我们可以在Hive中实现更复杂的业务逻辑。在实际应用中,还可以通过参数的类型和数量的不同实现更多种类的自定义函数,以满足具体的数据处理需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值