如何在MySQL中计算非标准季度的起止日期?
计算MySQL中非标准季度的起止日期
要处理季度起始月不是1月的场景(比如从2月、3月开始),核心思路是通过日期偏移将非标准季度对齐到MySQL默认的标准季度,计算完成后再偏移回原时间范围,以此避开QUARTER()函数仅支持标准季度的限制。
通用方法逻辑
- 反向偏移目标日期:偏移量等于非标准季度与标准季度的起始月差值(比如季度从2月开始,比标准季度提前1个月,就给目标日期减1个月)。
- 用标准逻辑计算起止:基于偏移后的日期,使用标准季度查询逻辑得到对应起止日期。
- 正向偏移还原日期:给计算出的起止日期加上相同的偏移量,得到非标准季度的真实起止时间。
场景1:季度提前1个月(2-4月、5-7月、8-10月、11-1月)
以目标日期2022-11-02为例,需要得到季度起始2022-11-01、结束2023-01-31,对应的SQL如下:
计算季度起始日期
SELECT MAKEDATE(YEAR('2022-11-02' - INTERVAL 1 MONTH), 1) + INTERVAL QUARTER('2022-11-02' - INTERVAL 1 MONTH) QUARTER - INTERVAL 1 QUARTER + INTERVAL 1 MONTH AS quarter_start;
执行结果:
+---------------+ | quarter_start | +---------------+ | 2022-11-01 | +---------------+
计算季度结束日期
SELECT MAKEDATE(YEAR('2022-11-02' - INTERVAL 1 MONTH), 1) + INTERVAL QUARTER('2022-11-02' - INTERVAL 1 MONTH) QUARTER - INTERVAL 1 DAY + INTERVAL 1 MONTH AS quarter_end;
执行结果:
+---------------+ | quarter_end | +---------------+ | 2023-01-31 | +---------------+
场景2:季度提前2个月(3-5月、6-8月、9-11月、12-2月)
如果季度从3月开始,只需将偏移量换成2即可。比如目标日期2022-11-02,对应的季度是9-11月,SQL如下:
计算季度起始日期
SELECT MAKEDATE(YEAR('2022-11-02' - INTERVAL 2 MONTH), 1) + INTERVAL QUARTER('2022-11-02' - INTERVAL 2 MONTH) QUARTER - INTERVAL 1 QUARTER + INTERVAL 2 MONTH AS quarter_start;
执行结果:
+---------------+ | quarter_start | +---------------+ | 2022-09-01 | +---------------+
计算季度结束日期
SELECT MAKEDATE(YEAR('2022-11-02' - INTERVAL 2 MONTH), 1) + INTERVAL QUARTER('2022-11-02' - INTERVAL 2 MONTH) QUARTER - INTERVAL 1 DAY + INTERVAL 2 MONTH AS quarter_end;
执行结果:
+---------------+ | quarter_end | +---------------+ | 2022-11-30 | +---------------+
复用性优化:使用变量统一控制偏移量
如果需要频繁切换偏移量,可用变量管理,更灵活:
SET @target_date = '2022-11-02'; SET @month_offset = 1; -- 偏移1个月=季度从2月开始;偏移2个月=季度从3月开始 -- 计算季度起始 SELECT MAKEDATE(YEAR(@target_date - INTERVAL @month_offset MONTH), 1) + INTERVAL QUARTER(@target_date - INTERVAL @month_offset MONTH) QUARTER - INTERVAL 1 QUARTER + INTERVAL @month_offset MONTH AS quarter_start; -- 计算季度结束 SELECT MAKEDATE(YEAR(@target_date - INTERVAL @month_offset MONTH), 1) + INTERVAL QUARTER(@target_date - INTERVAL @month_offset MONTH) QUARTER - INTERVAL 1 DAY + INTERVAL @month_offset MONTH AS quarter_end;
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

