weekofyear跨年问题

函数说明

  • 命令格式
bigint weekofyear (datetime <date>)
  • 参数说明
    date:必填。DATETIME类型日期值。格式为yyyy-mm-dd hh:mi:ss。如果输入为STRING类型,且MaxCompute项目的数据类型版本是1.0,则会隐式转换为DATETIME类型后参与运算。
  • 注意事项
    这一周算上一年还是下一年,取决于这一周的大多数日期(4天以上)在哪一年。算在前一年,就是前一年的最后一周;算在后一年就是后一年的第一周。

Bug现象

在这里插入图片描述

SELECT  WEEKOFYEAR(DATE '2021-01-01');
-- 53

上面的53 实际上是2020年的第53周

一般我们算一年的周数都是按照下面的sql处理的

SELECT CONCAT('2021',WEEKOFYEAR(DATE '2021-01-01'));
-- 202153

这样的话问题就来了,他其实是202053才对。因此我们不能简单的使用concat拼上年份,而是动态拼上year

解决

SELECT YEAR(date_sub(next_day('2021-01-01','monday'),4))*100 + WEEKOFYEAR(DATE '2021-01-01');
-- 202053
  • next_day函数

NEXT_DAY(date,char)
date参数为日期型,
char:为1–7或Monday/Mon~Sunday/

指定时间的下一个星期几(由char指定)所在的日期,
char也可用1~7替代,1表示星期日,2代表星期一

获取当前周、周的开始、结束时间

[0-6]
//周的开始时间
DATE_SUB(TO_DATE(ds,'yyyymmdd'),WEEKDAY(TO_DATE(ds,'yyyymmdd'))) as week_start,
//周的结束时间
DATE_SUB(TO_DATE(ds,'yyyymmdd'),WEEKDAY(TO_DATE(ds,'yyyymmdd')) - 6) as week_end
示例:

需求: 按周求uid的pv

SELECT  
    COUNT(DISTINCT uid),
    weekdate,
    collect_set(week_start)[0] as week_start,
    collect_set(week_end)[0] as week_end
FROM (
    SELECT 
        uid,
        TO_DATE(ds,'yyyymmdd'),
        CONCAT(YEAR(date_sub(next_day(TO_DATE(ds,'yyyymmdd'),'monday'),4)) ,'年第' ,WEEKOFYEAR(TO_DATE(ds,'yyyymmdd')),'周' ) AS weekdate,
        DATE_SUB(TO_DATE(ds,'yyyymmdd'),WEEKDAY(TO_DATE(ds,'yyyymmdd'))) as week_start,
        DATE_SUB(TO_DATE(ds,'yyyymmdd'),WEEKDAY(TO_DATE(ds,'yyyymmdd')) - 6) as week_end
        FROM huorong_bigdata.base_huorongsoftware_source01_detail
    WHERE fid IN (1,2,3,4,41,46) AND recname = 'Ransom/LockFile.ii'
    AND  ds >= '20221221' AND ds <= '20230301'
)t1
GROUP BY weekdate;

在这里插入图片描述

可以使用 Java 中的 Calendar 类来实现这个功能,具体步骤如下: 1. 获取传入日期的 Calendar 对象,并将其设置为传入日期。 2. 获取传入日期的星期几(1 表示星期天,2 表示星期一,以此类推)。 3. 将传入日期的 Calendar 对象往前推 1 天,直到星期几为星期五(5)为止。 4. 判断推回后的日期是否,如果则继续往前推,直到不为止。 5. 返回推回后的日期。 以下是实现代码示例: ```java import java.util.Calendar; public class LastFridayFinder { public static void main(String[] args) { Calendar calendar = Calendar.getInstance(); calendar.set(2021, 0, 4); // 设置传入日期为 2021 1 月 4 日 int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); // 获取传入日期的星期几 // 往前推日期直到星期五为止 while (dayOfWeek != Calendar.FRIDAY) { calendar.add(Calendar.DATE, -1); dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); } // 判断日期是否 int year = calendar.get(Calendar.YEAR); while (year != 2021) { calendar.add(Calendar.DATE, -7); year = calendar.get(Calendar.YEAR); } System.out.println("上五日期为:" + calendar.get(Calendar.YEAR) + "" + (calendar.get(Calendar.MONTH) + 1) + "月" + calendar.get(Calendar.DATE) + "日"); } } ``` 在上面的代码中,我们首先设置传入日期为 2021 1 月 4 日,然后往前推日期直到星期五为止。接着判断日期是否,如果则继续往前推,直到不为止。最后输出推回后的日期,即上五的日期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值