最近遇到一个需求,有一些统计数据,原本是按月更新的计算的,但是现在要按周更新计算。

在hive表中,月更数据一般按照一个月的最后一天进行分区存储,那么如果是按月更新的话直接根据分区进行计算就可以了。

而对于日更的数据,如果要按月计算的话,可以通过​​substr()​​函数将日期进行切分,取出只带月份的数据。

例如,对于​​dt = 2022-02-19​​​这个日期,可以通过​​substr(dt, 1, 7)​​​取出​​dt = 2022-02​​。

select substr('2022-02-19', 1, 7);

输出:

2022-02

但是如果要按周计算的话,单纯的​​substr()​​​就没法达到效果了,可以借助​​weekofyear()​​函数,它返回给定日期的周数(1到53之间的数字)。

例如,还是对于​​dt = 2022-02-19​​这个日期:

select weekofyear('2022-02-19');

输出:

7

代表​​2022-02-19​​是2022年的第7周。

但是这个函数还有一个问题,​​weekofyear()​​函数要求一年的第一周必须大于3天。

举个例子:

select weekofyear('2022-01-01');

输出:

52

这是什么情况?​​2022-01-01​​明明是2022年的第一天,输出个52是什么意思?

hive中如何进行按周计算_hadoop

原来​​2022-01-01​​是周六,前面有5天还在2021年,是2021年的第52周。

也就是说,​​2022-01-01​​​所在的周,只有两天在2022年,其余5天都在2021年,所以​​weekofyear()​​函数就认为这一周属于2021年的第52周。

那么怎么解决hive中跨年周的问题呢?

​weekofyear()​​函数要求一年的第一周必须大于3天,也就是说至少得有4天在某一年中。

所以,我们对于跨年那几天的日期,我们可以先得到它下周一的日期dt1,然后减去4天得到dt2,dt2所在的年份就是多的那一部分所在的年份,然后再拼上周数就可以啦。

例如:

select concat(year(date_sub(next_day('2022-01-01','monday'),4)), '-', weekofyear('2022-01-01'));

输出:

2021-52
select concat(year(date_sub(next_day('2021-12-31','monday'),4)), '-', weekofyear('2021-12-31'));

输出:

2021-52