mysql中YEARWEEK跨年引发的线上问题
问题源于一个测试小哥敏捷环境提的bug,简单描述一下场景,方便理解问题.现在有一个课程表查询功能,支持按照周为单位进行多个上周或是多个下周的课程表查询.支持复制当前一周课程表到下周,当天是2022.1.2,在当天复制本周课程表到下周之后切换到下周查询不到复制的课程信息.从数据库看数据库入表操作没有问题,创建时间是当天。
定位问题发现在于:YEARWEEK()函数.
业务中根据课程创建时间所在的周与当前日期时间所属周做比较,如果相同则会查询出课程信息,按照课程创建时间查询伪代码如下:
select * from course_table where
YEARWEEK(CURRENT_DATE(),1)+#{intervalWeek}=YEARWEEK(create_time,1)
intervalWeek表示课程表查询页面选择的周数,0表示查询当前时间周,1表示当前时间下一周,以此类推;-1表示当前时间上周,以此类推;2022.1.2所在周选择下一周时intervalWeek传递参数为1.
问题出现在周数加减上(2021-01-02所在周查询下一周课表时周数信息不一致导致).
SELECT YEARWEEK('2022-01-02',1)+1 -- 查询结果:202153
此时查询出来的周数信息加1之后是:202153,表示是2021年第53个周.但是实际上2021年是只有52个周(按照2022.01.03查询).
SELECT YEARWEEK('2022-01-03',1) -- 查询结果:202201
解决方案
按照mysql中提供的日期函数进行加减操作,新增类型(type为1时加指定周;为2时减指定周),减时用DATE_SUB,加时用DATE_ADD,当前周为0时两种方式都支持.伪代码如下:
select * from course_table
<where><if test="type==1">and YEARWEEK(DATE_FORMAT(start_time,'%Y-%m-%d' ),1) = YEARWEEK(DATE_ADD(CURRENT_DATE(),INTERVAL #{weekDay} WEEK),1)</if><if test="type==2">and YEARWEEK(DATE_FORMAT(start_time,'%Y-%m-%d' ),1) = YEARWEEK(DATE_SUB(CURRENT_DATE(),INTERVAL #{weekDay} WEEK),1)</if>
</where>
至于为何不对当前时间每年最后一周单独做处理的原因如下:查询近几年数据发现,以每年的第一个星期日来看,mysql查询出来的最后一周有的是52周,有的是53周,不便于做判断.
select YEARWEEK('2022-01-02',1) -- 查询结果:202152 select YEARWEEK('2022-01-03',1) -- 查询结果:202201 select YEARWEEK('2021-01-03',1) -- 查询结果:202053 select YEARWEEK('2021-01-04',1) -- 查询结果:202101select YEARWEEK('2019-12-29',1) -- 查询结果:201952select YEARWEEK('2020-01-05',1) -- 查询结果:202001select YEARWEEK('2019-12-29',1) -- 查询结果:201852select YEARWEEK('2019-01-06',1) -- 查询结果:201901
总结:平常使用mysql函数要多关注临界值,不然平常没有问题,特殊情况就会出现大问题,上面的场景如果不是跨年也不会暴露出问题。
YEARWEEK()以及DATE_SUB()函数以及其他常用函数参考: mysql常用函数使用场景总结(持续更新)
mysql中YEARWEEK跨年引发的线上问题相关推荐
- 用 gson 替换 fastjson 引发的线上问题分析
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 前言 Json 序列化框架存在的安全漏洞一直以来都是程序 ...
- “���”引发的线上事故
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 最近遇到了一起依赖升级 + 异常数据引发的线上事故,教训惨痛,本文 ...
- MyBatis版本升级引发的线上告警回顾及原理分析
本文从一次MyBatis版本升级引发的线上告警开始讲起,然后针对告警定位过程.源码原理进行了深入的分析,并加入了不同版本的类比分析,最后结合实际工作做了一些经验总结,希望能对大家的工程实践有一定的帮助 ...
- MySQL源码学习:MySQL中禁止跨库访问的实现
摘要: 先说一下这里"跨库"的意思:当前use的是db1, 仍可以使用select * from db2.table1来访问table1表. 这样使得我们需要访问同一个MySQL ...
- mysql时区错乱_记一次线上mysql时区错乱
Mysql查询时间和页面显示时间相差八个小时. 在一次线上程序调用mysql内部函数转化时间戳的时候的bug记录.在本地开发与测试环境都没得问题.但是上线后,程序总是不再状态. 遂开启审阅代码的过程, ...
- 中英同声传译,线上同声传译服务
疫情期间,线上会议需求量激增,英信翻译升级同传翻译功能,制定线上同传大会解决方案,可远程快速接入,以线上同传(云同传)形式为大会提供全流程实时同传翻译服务. 3月份,"中信证券年度业绩交流会 ...
- mysql连接池泄露_一次线上故障:数据库连接池泄露后的思考
作者:陈朗,普兰金融科技能效工程部开发工程师 一:初步排查 早上作为能效平台系统的使用高峰期,系统负载通常比其它时间段更大一些,某个时间段会有大量用户登录.当天系统开始有用户报障,发布系统线上无法构建 ...
- mysql中datediff跨年的用法_Mysql 函数使用记录(一)——DATEDIFF、CONCAT
当目前为止呢,个人对Mysql的函数没有进行过统一的学习使用,都是用到了再去学习.而近日开始学习Linux了,所以为了防止这段时期结束后,将此阶段期间遇到的Mysql函数遗忘,开始在此对其做一个简单的 ...
- mysql 线上加索引_mysql手札,唯一索引引发的线上事故
昨天把一个数据表的字段从普通索引,修改成为了唯一索引.准备早早下班的时候,突然发现数据库的内存命中率从98%下降到了48%,导致大量的任务处于阻塞状态,整个系统也阻塞了. 其实这个就是普通索引和唯一索 ...
- Eclipse中的集成Git插件删除线上远程分支
Eclipse 的忠实党,在使用Git 多人协作以分支的形式开发应用时分支合并到主干后往往再没什么用(我的做法是保留一两周再干掉),在此记录使用Eclipse的Git 插件来删除无用的分支. 操作步骤 ...
最新文章
- java中的保留字_Java中的保留字是哪些呢?
- BZOJ 3237: [Ahoi2013]连通图
- 美赛开赛在即,你准备好了吗?
- C语言之scanf中的格式
- PID控制器开发笔记之五:变积分PID控制器的实现
- linux mem设备是什么,linux下/dev/mem分析
- 公众号获取token失败_恶意请求微信公众号token,导致access_token超过10万次解决思路...
- 《游戏设计、原型与开发——基于Unity与C#从构思到实现》学习笔记一
- 如何快速安装rational rose
- CREO学习笔记【钣金结构中常用的标准件】
- php操作阿里云短信API接口
- 测绘大王的GPS盛宴
- 200道Java灵魂考题:全部掌握拿下阿里P7腾讯T3.2
- 蓝牙定位技术原理,蓝牙定位应用场景-室内定位-新导智能
- 计算机病毒模块测试题,计算机病毒分类测试题集
- java vcf_Java VCF 格式解析
- 基于ssm java乐轩公司订餐系统
- java 调用 yed 绘制 流程图_让人一见倾心的流程图绘制软件yEd
- 使用app管理家庭路由器(TP-Link,水星,腾达等)
- 使用 ffmpeg 转码 视频 (使用 nvidia 硬件加速 和 h265 编码)