MySQL如何批量筛选多组指定天数间隔波动范围内的邀请记录
批量筛选间隔指定天数区间的邀请记录查询方案
我有一个invites表,需要查询所有创建时间满足以下条件的邀请记录:以今日为基准,落在每间隔指定天数(比如90天)的时间点附近,且每个时间点允许前后指定天数(比如2天)的波动范围——也就是筛选创建时间在88-92天前、178-182天前、268-272天前这类区间的记录。
目前我通过手动重复WHERE子句的OR条件实现了固定几组区间的查询,代码如下:
SET @days_span = 90; SET @days_variance = 2; SELECT invites.id, invites.date_created_utc FROM invites WHERE -- 88-92天前区间 invites.date_created_utc BETWEEN date_sub(utc_timestamp(), interval (@days_span + @days_variance) DAY) AND date_sub(utc_timestamp(), interval (@days_span - @days_variance) DAY) -- 178-182天前区间 OR invites.date_created_utc BETWEEN date_sub(utc_timestamp(), interval (@days_span * 2 + @days_variance) DAY) AND date_sub(utc_timestamp(), interval (@days_span * 2 - @days_variance) DAY) -- 268-272天前区间 OR invites.date_created_utc BETWEEN date_sub(utc_timestamp(), interval (@days_span * 3 + @days_variance) DAY) AND date_sub(utc_timestamp(), interval (@days_span * 3 - @days_variance) DAY); -- 更多区间需手动追加
但这种方式无法扩展到任意数量的区间,现寻求可批量处理的解决方案。
方案一:递归CTE生成倍数序列关联查询
通过递归CTE生成连续的倍数(1、2、3...n),再与invites表关联匹配区间,可灵活控制需要覆盖的区间数量:
SET @days_span = 90; SET @days_variance = 2; SET @max_multiplier = 10; -- 按需调整最大倍数,覆盖目标时间范围 WITH RECURSIVE multipliers AS ( SELECT 1 AS n UNION ALL SELECT n + 1 FROM multipliers WHERE n < @max_multiplier ) SELECT DISTINCT invites.id, invites.date_created_utc FROM invites JOIN multipliers ON invites.date_created_utc BETWEEN date_sub(utc_timestamp(), interval (@days_span * multipliers.n + @days_variance) DAY) AND date_sub(utc_timestamp(), interval (@days_span * multipliers.n - @days_variance) DAY);
- 使用
DISTINCT避免单条记录被多个区间匹配时重复输出 @max_multiplier决定生成的区间数量,可根据数据的历史时长调整
方案二:数学计算直接判断
通过计算创建时间距今日的天数,判断其与最近的@days_span倍数的差值是否在波动范围内,无需生成序列:
SET @days_span = 90; SET @days_variance = 2; SELECT id, date_created_utc FROM invites WHERE -- 计算当前天数与最近的@days_span倍数的差值绝对值 ABS( DATEDIFF(utc_timestamp(), date_created_utc) - @days_span * FLOOR(DATEDIFF(utc_timestamp(), date_created_utc) / @days_span) ) <= @days_variance -- 排除不足@days_span - @days_variance天的记录(避免匹配0倍区间) AND DATEDIFF(utc_timestamp(), date_created_utc) >= @days_span - @days_variance;
这种方法会自动覆盖所有符合条件的历史区间,无需手动设置最大倍数,适合不确定需要覆盖多少个区间的场景。
内容的提问来源于stack exchange,提问作者Carel
相关产品推荐
相关产品推荐

