前言
前段时间,做了一个日期维度表的需求,发现 计算当年第几周 有误,发现 Hive
中 weekofyear
函数存在跨年问题!
跨年问题
这一周算上一年还是下一年,取决于这一周的大多数日期(4天及以上)在哪一年。算在前一年,就是前一年的最后一周;算在后一年就是后一年的第一周。
比如下面这种情况:
2022年最后6天(>=4天)和2023年第一天在一周内,那么2023-01-01就会算在前一年的最后一周!
SELECT WEEKOFYEAR('2023-01-01'); -- 52
上面的 52, 实际上是2022年的第52周!
但是有个问题:按正常人的逻辑来看,2023-01-01 不应该算到2022年的第52周,而是2023年的第一周,2023-01-02 到 2023-01-08 应该算是2023年的第二周…
SELECT WEEKOFYEAR('2023-01-02'); -- 1
实际通过 WEEKOFYEAR
获取 2023-01-02 是2023年的第一周了,这样就和正常人的逻辑有出入了!
计算当年第几周
select CASE WHEN YEAR(DATE_SUB(NEXT_DAY(curr_date,'monday'),4)) < CAST(SUBSTR(curr_date,1,4) as int) THEN 1 WHEN YEAR(DATE_SUB(NEXT_DAY(curr_date,'monday'),4)) > CAST(SUBSTR(curr_date,1,4) as int) THEN WEEKOFYEAR(DATE_SUB(TO_DATE(curr_date),4))+1 ELSE if(WEEKOFYEAR(TO_DATE(concat(SUBSTR(curr_date,1,4),'-01-01')))>1, WEEKOFYEAR(curr_date)+1,WEEKOFYEAR(curr_date)) END AS TH_YEAR_WOM;
curr_date :要计算的某个日期
NEXT_DAY(curr_date,‘monday’):计算curr_date的下一个星期一的日期
YEAR(DATE_SUB(NEXT_DAY(curr_date,‘monday’),4)) :计算curr_date的周数所在年份
- 如果
周数所在年份 < 当前年份
,表示当前年的前几天,属于前一年的最后一周,而我们想要的是当前年的第一周。 - 如果
周数所在年份 < 当前年份
,表示当前年的最后几天,属于后一年的第一周,而我们想要的是当前年的最后一周。 - 如果
周数所在年份 = 当前年份
,表示当前年的中间的日期,假如当前年的第一天属于前一年的最后一周
,那么我们想要的周数 =WEEKOFYEAR(curr_date)+1
以上就是按照我们正常人的逻辑,计算当年第几周!