如何修改MySQL查询以获取指定日期范围内的每隔一个周二
解决方案:获取区间内每隔一个周二的日期
这问题挺常见的,要拿到2018-05-21至2018-08-31范围内每隔一周的周二,咱们有两种实用方案,分别适配不同版本的MySQL:
方案一:使用递归CTE(MySQL 8.0及以上版本推荐)
递归CTE是最简洁的方式,先找到区间内的第一个周二,之后每次递加14天(两周)生成后续日期,直到超过结束日期:
WITH RECURSIVE tuesdays AS ( -- 找到区间内第一个>=起始日期的周二 SELECT CASE WHEN DAYOFWEEK('2018-05-21') = 3 THEN '2018-05-21' -- DAYOFWEEK中周二是3 ELSE ADDDATE('2018-05-21', (3 - DAYOFWEEK('2018-05-21') + 7) % 7) END AS tuesday_date UNION ALL -- 每次加14天生成下一个隔周的周二 SELECT ADDDATE(tuesday_date, 14) FROM tuesdays WHERE ADDDATE(tuesday_date, 14) <= '2018-08-31' ) SELECT tuesday_date AS DATES FROM tuesdays;
逻辑解释:
DAYOFWEEK()函数中,周日是1,周二是3,所以我们先判断起始日期是不是周二,如果是直接用,否则计算距离下一个周二的天数。- 递归部分每次给当前日期加14天,确保只生成隔一周的周二,直到日期超过结束日期为止。
方案二:基于原查询修改(兼容低版本MySQL)
如果你的MySQL版本不支持递归CTE,可以在原查询的基础上给筛选出的周二添加行号,然后只保留行号为奇数(或偶数)的记录,实现“每隔一个”的效果:
SELECT DATES FROM ( SELECT DATES, @row_num := @row_num + 1 AS row_number FROM ( -- 原查询的日期生成逻辑 SELECT adddate('1970-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) DATES FROM (select 0 t0 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0, (select 0 t1 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1, (select 0 t2 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2, (select 0 t3 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3, (select 0 t4 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4 ) v WHERE DATES between '2018-05-21' and '2018-08-31' and dayname(DATES) in ('TUESDAY') ORDER BY DATES ) ranked_tuesdays -- 选择奇数行(取第1、3、5...个周二),如果要从第二个周二开始取,改成row_number % 2 = 0 WHERE row_number % 2 = 1;
逻辑解释:
- 我们用用户变量
@row_num给每个按日期排序的周二分配递增的行号。 - 通过
row_number % 2 = 1筛选出奇数行的周二,也就是每隔一个取一个;如果想从区间内的第二个周二开始取,改成row_number % 2 = 0即可。
内容的提问来源于stack exchange,提问作者MZWEI
相关产品推荐
相关产品推荐

