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

news2024/10/6 10:32:55

一、问题

按每年的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 1
        ELSE 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

除了第一行,每一行都相差 8

8 可以拆解为 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;





SELECT
    your_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 1
        ELSE 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.coloradmin.cn/o/1204861.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯 插入排序

插入排序的思想 插入排序是一种简单直观的排序算法&#xff0c;其基本思想是将待排序的元素逐个插入到已排序序列 的合适位置中&#xff0c;使得已排序序列逐渐扩大&#xff0c;从而逐步构建有序序列&#xff0c;最终得到完全有序的序 列。 它类似于我们打扑克牌时的排序方式&…

缅因州政府通知130万人MOVEit数据泄露事件

大家好&#xff0c;今天我要向大家通报一个令人震惊的消息&#xff1a;缅因州政府的系统遭到了入侵&#xff0c;黑客利用MOVEit文件传输工具的漏洞&#xff0c;获取了约130万人的个人信息&#xff0c;这几乎相当于该州的整个人口数量。 MOVEit攻击是Clop勒索软件团伙进行的一次…

数据结构(超详细讲解!!)第二十三节 树型结构

1.定义 树型结构是一类重要的非线性数据结构&#xff0c;是以分支关系定义的层次结构。是一种一对多的逻辑关系。 树型结构是结点之间有分支&#xff0c;并且具有层次关系的结构&#xff0c;它非常类似于自然界中的树。树结构在客观世界中是大量存在的&#xff0c;例如家谱、…

nginx代理docker容器服务

场景描述 避免暴力服务端口&#xff0c;使用nginx代理 一个前端&#xff0c;一个后端&#xff0c;docker方式部署到服务器&#xff0c;使用docker创建的nginx代理端口请求到前端端口 过程 1 docker 安装nginx 1.1 安装一个指定版本的nginx docker pull nginx#启动一个ngi…

【MySQL】对表结构进行增删查改的操作

表的操作 前言正式开始建表查看表show tables;desc xxx;show create table xxx; 修改表修改表名 rename to对表结构进行修改新增一个列 add 对指定列的属性做修改 modify修改列名 change 删除某列 drop 删除表 drop 前言 前一篇讲了库相关的操作&#xff0c;如果你不太懂&…

麒麟信安:助力医疗行业操作系统自主创新,提升可靠性与安全性

应用场景 湖南省康复医院是省卫生健康委直属公立三级康复医院&#xff0c;也是全省唯一一所集预防、医疗、康复、科研、教学、健康管理为一体的省级三级公立康复医院。 湖南省康复医院使用的医慧管平台由湖南蓝途方鼎科技有限公司开发&#xff0c;利用互联网技术&#xff0c;…

好题分享(2023.11.5——2023.11.11)

目录 前情回顾&#xff1a; 前言&#xff1a; 题目一&#xff1a;补充《移除链表元素》 题目二&#xff1a;《反转链表》 解法一&#xff1a;三指针法 解法二&#xff1a;头插法 题目三&#xff1a; 《相交链表》 题目四&#xff1a;《合并两个有序数列》 题目五&…

vmware 修改主机名称 hadoop 服务器环境配置(一)

如何在虚拟机配置主机名称&#xff1a; 1. 如图所示在/etc 文件夹下有个hosts文件。追加映射关系&#xff1a; #关系 ip地址 名称 192.168.164.20 hadoop20 2. 保存后&#xff0c;重启reboot即可

炸裂!Sklearn 的 10 个宝藏级使用方法!

大家好&#xff0c;本次给大家介绍10个Sklearn方法&#xff0c;比较小众但非常好用。 1️.FunctionTransformer 虽然Sklearn中有很多内置的预处理操作可以放进pipeline管道&#xff0c;但很多时候并不能满足我们的需求。 如果是比较简单并且通过一个函数可以实现需求的情况&…

考前须知-2024年上半年系统集成项目管理工程师

可以看看23年下半年软考集成考试的难度 一、考试时间安排&#xff1a; 集成考试一年会考2次&#xff0c;上半年一次、下半年一次。考试时间4h&#xff0c;分批进行 系统集成项目管理工程师教材共655页&#xff0c;分为23章。其中,前3章为信息化与系统集成基础知识的内容,第4章…

4.5 构建onnx结构模型-Reshape

前言 构建onnx方式通常有两种&#xff1a; 1、通过代码转换成onnx结构&#xff0c;比如pytorch —> onnx 2、通过onnx 自定义结点&#xff0c;图&#xff0c;生成onnx结构 本文主要是简单学习和使用两种不同onnx结构&#xff0c; 下面以pow 结点进行分析 方式 方法一&am…

C语言之初阶指针

一、指针&#xff1a; 其实按照我的理解&#xff0c;当我们写c语言程序的时候&#xff0c;创建的变量&#xff0c;数组等都要在内存上开辟空间。而每一个内存都有一个唯一的编号&#xff0c;这个编号也被称为地址编号&#xff0c;就相当于&#xff0c;编号地址指针。 二、指针…

STM32F4 GPIO端口二极管作用——二极管钳位作用

如上图所示&#xff0c;有两个保护二极管&#xff0c;用于保护内部电路&#xff0c;防止I\O引脚外部过高或者过低的电压输入时造成内部电路损坏。 具体来讲&#xff1a;当引脚输入电压高于VDD时&#xff0c;上面的二极管导通&#xff0c;输入点电压被钳位到约VDD0.7V&#xff…

python打包部署脚本

linux可使用expect来实现自动交互&#xff0c;windows想要写出同样的功能脚本&#xff0c;只能使用python或者安装ActiveTcl 1、安装python Microsoft Store搜索python直接安装&#xff0c;默认会直接添加到环境变量https://www.python.org/官网下载&#xff0c;点击安装时会提…

比尔·盖茨谈他对软件应用和人工智能代理未来的见解

比尔盖茨在他的 Gatesnotes 网站中发表了一篇文章&#xff0c;分享了他对软件应用和人工智能代理未来的见解。他认为人工智能代理将大行其道&#xff0c;在接下来的五年里&#xff0c;这将完全改变。你不需要为不同的任务使用不同的应用程序。你只需用日常语言告诉你的设备你想…

基于Python优化图片亮度与噪点

支持添加噪点类型包括&#xff1a;添加高斯噪点、添加椒盐噪点、添加波动噪点、添加泊松噪点、添加周期性噪点、添加斑点噪点、添加相位噪点&#xff0c;还提供清除噪点的功能。 我们先看一下实测效果&#xff1a;&#xff08;test.jpg为原图&#xff0c;new.jpg为添加后的图片…

基于JavaWeb+SSM+校园零售商城微信小程序系统的设计和实现

基于JavaWebSSM校园零售商城微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 摘 要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应…

HRNet关键点检测

HRNet是一种用于关键点检测的网络架构&#xff0c;它具有一些优点和缺点。 优点&#xff1a; 可以保持高分辨率&#xff1a;HRNet将高分辨率到低分辨率的子网并联连接&#xff0c;而不是像大多数现有解决方案那样串联连接。因此&#xff0c;HRNet能够保持高分辨率&#xff0c…

动态修改hosts

前言 因工作需要频繁变更hosts&#xff0c; 故须自己实现一个动态管理器&#xff0c; 市面上其实已经有了类似的软件&#xff0c;比如switchhosts!但因为不好集成其他功能&#xff08;如远程连接KVM&#xff09;&#xff0c;所以还是决定自己开发一套。 原理 使用之前强烈建…

tcpdump抓包的字节数量与ethtool统计数据不同的原因

情况介绍 在进行RDMA抓包流量分析时&#xff0c;我使用ethtool工具统计了RDMA网卡的流量发送数据数量&#xff0c;然后使用tcpdump进行抓包。 经过分析发现&#xff0c;tcpdump得到的数据数量总是大于ethtool得到的数据数量&#xff0c;而且每个数据包会多出4个字节。 分析 …