Spark SQL 每年的1月1日算当年的第一个自然周, 给出日期,计算是本年的第几周

一、问题

按每年的1月1日算当年的第一个自然周
(遇到跨年也不管,如果1月1日是周三,那么到1月5号(周日)算是本年的第一个自然周, 如果按周一是一周的第一天)
计算是本年的第几周,那么 spark sql 如何写 ?

二、分析

难点 :

  1. Spark SQL 的 DAYOFWEEK 函数返回的每周第一天是周日。
  2. 边界值的处理,即第一周如何判定、第二周从哪天开始计算。

先给出 sql 关键逻辑

    CASE WHEN DAYOFYEAR(your_date_column) <= 7 AND DAYOFWEEK(your_date_column) <> 2 THEN 1ELSE CEIL((DAYOFYEAR(your_date_column) - DAYOFWEEK(your_date_column) + 8) / 7.0)END AS week_number

多找一些边界值测试一下。

DAYOFWEEK(your_date_column)分别返回

周日		周一 	周二 	周三		周四		周五		周六
1		2		3		4		5		6		7

当1月1日是周一时,DAYOFWEEK(your_date_column) 返回 2(Spark SQL 中周一是2)。
当1月1日是周日时,DAYOFWEEK(your_date_column) 返回 1。但是 1月1日都是当年的第一天,即 1月1日在 DAYOFYEAR(your_date_column) 永远都返回 1。当1月1日是周日时,DAYOFYEAR(your_date_column) - DAYOFWEEK(your_date_column)  =  1 - 1 =  0      第二周第一天 1月2日 = 2 - 1 = 1
当1月1日是周一时,DAYOFYEAR(your_date_column) - DAYOFWEEK(your_date_column)  =  1 - 2 = -1      第二周第一天 1月8日 = 8 - 1 = 7
当1月1日是周二时,DAYOFYEAR(your_date_column) - DAYOFWEEK(your_date_column)  =  1 - 3 = -2      第二周第一天 1月7日 = 7 - 1 = 6
当1月1日是周三时,DAYOFYEAR(your_date_column) - DAYOFWEEK(your_date_column)  =  1 - 4 = -3      第二周第一天 1月6日 = 6 - 1 = 5
当1月1日是周四时,DAYOFYEAR(your_date_column) - DAYOFWEEK(your_date_column)  =  1 - 5 = -4      第二周第一天 1月5日 = 5 - 1 = 4
当1月1日是周五时,DAYOFYEAR(your_date_column) - DAYOFWEEK(your_date_column)  =  1 - 6 = -5      第二周第一天 1月4日 = 4 - 1 = 3
当1月1日是周六时,DAYOFYEAR(your_date_column) - DAYOFWEEK(your_date_column)  =  1 - 7 = -6      第二周第一天 1月3日 = 3 - 1 = 2除了第一行,每一行都相差 88 可以拆解为 7 + 1,7 代表第二周, 1 代表第二周的第一天定义,偏移了 1。举个例子,如果 your_date_column 是 2024-01-08(这是一个周二),DAYOFYEAR 为 8,DAYOFWEEK 为 3(周二),
那么计算将是 CEIL((8 - 3 + 8) / 7.0),即 CEIL(13 / 7.0),结果为 2,意味着这是第二周。

还有一种思考方式,去理解  7 + 1 中的 1 ,DAYOFWEEK(your_date_column)  返回 1~7 , 如果除以 7 的话,为了确保不进位 1,那么需要把 1~7 向左偏移一位。 1~7 - 1 = 0~6
DAYOFYEAR(your_date_column) -  ( DAYOFWEEK(your_date_column) - 1 ) / 7 都是在同一周

在这里插入图片描述
2023-01-01 年是周日,
那么 DAYOFWEEK(your_date_column) 返回的是 1,即本周第一天。
WEEKOFYEAR(your_date_column) 返回的是 52, 即 2022 年最后一周。
但实际上我们要求的结果应该是 2023 年的第一周。

2023-01-02 年是周一,
那么 DAYOFWEEK(your_date_column) 返回的是 2,即本周第二天。
WEEKOFYEAR(your_date_column) 返回的是 1, 即 2023 年第一周。
但实际上我们要求的结果应该是 2023 年的第二周。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

三、验证


drop table your_table;CREATE TABLE your_table (id INT,your_date_column DATE
);CREATE OR REPLACE TEMPORARY VIEW temp_view AS 
SELECT 1 as id, to_date('2023-01-01', 'yyyy-MM-dd') as your_date_column
UNION ALL
SELECT 2, to_date('2023-01-02', 'yyyy-MM-dd')
UNION ALL
SELECT 3, to_date('2023-02-15', 'yyyy-MM-dd')
UNION ALL
SELECT 4, to_date('2023-12-31', 'yyyy-MM-dd')
UNION ALL
SELECT 5, to_date('2024-01-01', 'yyyy-MM-dd')
UNION ALL
SELECT 6, to_date('2024-01-02', 'yyyy-MM-dd')
UNION ALL
SELECT 5, to_date('2024-01-07', 'yyyy-MM-dd')
UNION ALL
SELECT 6, to_date('2024-01-08', 'yyyy-MM-dd');INSERT INTO your_table
SELECT * FROM temp_view;SELECTyour_date_column,YEAR(your_date_column) AS year,date_format(your_date_column, 'EEEE') as WEEK,WEEKOFYEAR(your_date_column) as WEEK_OF_YEAR,DAYOFYEAR(your_date_column) as DAYOFYEAR,DAYOFWEEK(your_date_column) as DAYOFWEEK,CEIL((DAYOFYEAR(your_date_column) - DAYOFWEEK(your_date_column) + 8) / 7.0) as CEIL,CASE WHEN DAYOFYEAR(your_date_column) <= 7 AND DAYOFWEEK(your_date_column) <> 2 THEN 1ELSE CEIL((DAYOFYEAR(your_date_column) - DAYOFWEEK(your_date_column) + 8) / 7.0)END AS week_number
from your_table;
your_date_column    year    WEEK            WEEK_OF_YEAR    DAYOFYEAR   DAYOFWEEK   CEIL    WEEK_NUMBER
2023-01-01	        2023	Sunday	        52	            1	        1	        2	    1
2023-01-02	        2023	Monday	        1	            2	        2	        2	    2
2023-02-15	        2023	Wednesday	    7	            46	        4	        8	    8
2023-12-31	        2023	Sunday	        52	            365	        1	        54	    54
2024-01-01	        2024	Monday	        1	            1	        2	        1	    1
2024-01-02	        2024	Tuesday	        1	            2	        3	        1	    1
2024-01-07	        2024	Sunday	        1	            7	        1	        2	    1
2024-01-08	        2024	Monday	        2	            8	        2	        2	    2在这个查询中:
date_format 函数的第二个参数 'EEEE' 指定返回完整的星期名称(如 Monday, Tuesday 等)。
DAYOFYEAR(your_date_column) 计算出年中的天数。
DAYOFWEEK(your_date_column) 返回一周中的某天(以周日为一周的第一天)。
当 DAYOFYEAR 小于或等于7且 DAYOFWEEK 不等于2(不是周一)时,日期属于第一周。
否则,使用调整后的公式计算周数:减去 DAYOFWEEK 的结果,加上8,然后除以7,并向上取整。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/171211.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

0基础学习PyFlink——水位线(watermark)触发计算

在《0基础学习PyFlink——个数滚动窗口(Tumbling Count Windows)》和《0基础学习PyFlink——个数滑动窗口&#xff08;Sliding Count Windows&#xff09;》中&#xff0c;我们发现如果窗口中元素个数没有把窗口填满&#xff0c;则不会触发计算。 为了解决长期不计算的问题&a…

Arthas(阿尔萨斯)--(二)

目录 一、Arthas学习 1、JVM相关命令一 1、dashboard 2、thread 3、jvm 4、sysprop 一、Arthas学习 Arthas(阿尔萨斯)--(一) Arthas代码开源地址 1、JVM相关命令一 1、dashboard dashboard:显示当前系统的实时数据面板&#xff0c;按q或ctrlc退出 ID: Java 级别的线…

Docker - 容器数据卷

Docker - 容器数据卷 什么是容器数据卷 等同于挂载&#xff0c;将容器内的目录地址指向于宿主机文件系统中 直接使用命令来挂载 -v docker run -it -v 主机目录:容器内目录# 测试 docker run -it -v /root:/home centos /bin/bash [rootiZ2zeg7mctvft5renx1qvbZ ~]# docker …

vscode 快速打印console.log

第一步 输入这些 {// Print Selected Variabl 为自定义快捷键中需要使用的name&#xff0c;可以自行修改"Print Selected Variable": {"body": ["\nconsole.log("," %c $CLIPBOARD: ,"," background-color: #3756d4; padding:…

Linux---(六)自动化构建工具 make/Makefile

文章目录 一、make/Makefile二、快速查看&#xff08;1&#xff09;建立Makefile文件&#xff08;2&#xff09;编辑Makefile文件&#xff08;3&#xff09;解释&#xff08;4&#xff09;效果展示 三、背后的基本知识、原理&#xff08;1&#xff09;如何清理对应的临时文件呢…

Js 语句

JavaScript 语句向浏览器发出的命令&#xff0c;语句的作用是告诉浏览器该做什么&#xff1b;分号用于分隔 JavaScript 语句&#xff0c;通常我们在每条可执行的语句结尾添加分号&#xff1b;使用分号的另一用处是在一行中编写多条语句。 JavaScript 语句通常以一个 语句标识符…

postgreSQL中的高速缓存

1. 高速缓存简介 ​如下图所示&#xff0c;当一个postgreSQL进程读取一个元组时&#xff0c;需要获取表的基本信息&#xff08;例如&#xff1a;表的oid、索引信息和统计信息等&#xff09;及元组的模式信息&#xff0c;这些信息被分别记录在多个系统表中。通常一个表的模式信…

2023年数维杯国际大学生数学建模挑战赛A题

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 cs数模团队在数维杯前为大家提供了许多资料的内容呀&#xff0…

ios 对话框UIAlertController放 tableview

//强弱引用 #define kWeakSelf(type)__weak typeof(type)weak##type type; -(void) showUIAlertTable {kWeakSelf(self)UIAlertController *alert [UIAlertController alertControllerWithTitle:NSLocalizedString("select_stu", nil) message:nil prefer…

基于php+thinkphp的网上书店购物商城系统

运行环境 开发语言&#xff1a;PHP 数据库:MYSQL数据库 应用服务:apache服务器 使用框架:ThinkPHPvue 开发工具:VScode/Dreamweaver/PhpStorm等均可 项目简介 系统主要分为管理员和用户二部分&#xff0c;管理员主要功能包括&#xff1a;首页、个人中心、用户管理、图书分类…

P6入门:项目初始化5-项目支出计划Spending Plan

前言 使用项目详细信息查看和编辑有关所选项目的详细信息&#xff0c;在项目创建完成后&#xff0c;初始化项目是一项非常重要的工作&#xff0c;涉及需要设置的内容包括项目名&#xff0c;ID,责任人&#xff0c;日历&#xff0c;预算&#xff0c;资金&#xff0c;分类码等等&…

Spark3.0中的AOE、DPP和Hint增强

1 Spark3.0 AQE Spark 在 3.0 版本推出了 AQE&#xff08;Adaptive Query Execution&#xff09;&#xff0c;即自适应查询执行。AQE 是 Spark SQL 的一种动态优化机制&#xff0c;在运行时&#xff0c;每当 Shuffle Map 阶段执行完毕&#xff0c;AQE 都会结合这个阶段的统计信…