You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 12:55:25