MySQL如何正确实现YEARWEEK列值减一周的计算
MySQL整数类型YEARWEEK值计算上一周的正确方案
直接对整数格式的YEARWEEK值做算术减1、或者字符串截取拼接的方案都无法覆盖所有边界场景,核心原因是YEARWEEK的年份和周数不是独立的十进制数位,跨年、存在53周的年份场景下手动运算必然出错,最稳妥的方案是借助MySQL原生日期函数做转换计算,不需要自己写边界判断逻辑。
实现逻辑
整个计算链路完全复用MySQL内置的周规则逻辑,和你生成存储YEARWEEK值时的规则保持100%一致:
- 将整数格式的YEARWEEK值解析为对应周的固定基准日期(比如当周第一天)
- 将基准日期往前推7天,得到上一周的基准日期
- 对上一周的基准日期调用
YEARWEEK()函数,输出的结果就是准确的上一周YEARWEEK值,自动兼容跨年、53周等所有边界场景。
代码示例
注意:YEARWEEK()函数支持多套周计数规则,调用时第二个参数必须和你当初生成存储YEARWEEK值时用的模式完全匹配,否则会出现结果偏差。
最常用的**周一为一周起始、周数范围1-53(模式3)**场景,计算代码如下:
SELECT yw_int_col, -- 计算上一周YEARWEEK值 YEARWEEK( DATE_SUB( STR_TO_DATE(CONCAT(yw_int_col, ' Monday'), '%x%v %W'), INTERVAL 7 DAY ), 3) AS prev_yw_int_col FROM your_calendar_table;
结果验证
- 输入值202230:解析得到2022年第30周周一,减7天为2022年第29周周一,返回202229,结果正确
- 输入值202301:解析得到2023年第1周周一,减7天为2022年第52周周一,返回202252,结果正确
- 输入值202101(2020年存在53周):解析得到2021年第1周周一,减7天为2020年第53周周一,返回202053,自动兼容53周场景
如果你存储的YEARWEEK值是用默认模式(周日为一周起始、周数范围0-53,模式0)生成的,使用下面的代码即可:
SELECT yw_int_col, YEARWEEK( DATE_SUB( STR_TO_DATE(CONCAT(yw_int_col, ' Sunday'), '%X%V %W'), INTERVAL 7 DAY ), 0) AS prev_yw_int_col FROM your_calendar_table;
为什么不推荐手动运算
如果用字符串截取年、周部分手动计算,你需要额外维护两套判断逻辑:
- 当周数为1时,上一周属于上一年
- 每一个年份的总周数是52还是53
这套逻辑容易漏判边界,后续维护成本高,而原生函数方案不需要额外处理任何特殊场景,结果和内置YEARWEEK()的输出规则完全一致,不会出现偏差。
内容的提问来源于stack exchange,提问作者Svk
相关产品推荐
相关产品推荐

