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

SQL如何查询同一日期段内存在重复折扣记录的用户

筛选存在重叠折扣记录用户的SQL实现方案

前提假设

discounts表包含以下核心字段:

  • user:用户唯一标识
  • start_date:折扣生效起始日期
  • end_date:折扣失效结束日期
  • id:折扣记录主键(可选,用于唯一识别单条记录)

核心逻辑:时间区间重叠判断

两个时间区间 [s1, e1] 和 [s2, e2] 存在重叠的通用判断条件为:
s1 < e2 AND s2 < e1
如果业务规则中「前一条折扣到期日 = 后一条折扣起始日」不算重叠,可将<调整为<=。

实现方案

方案1:自连接实现(易理解)

通过自连接匹配同用户的不同折扣记录,校验是否存在重叠,适合数据量较小的场景:

SELECT DISTINCT d1.user
FROM discounts d1
JOIN discounts d2
  ON d1.user = d2.user
  AND d1.id < d2.id -- 避免同一条记录和自己匹配,也避免重复匹配同一对记录
  AND d1.start_date < d2.end_date
  AND d2.start_date < d1.end_date
ORDER BY d1.user;

如果表没有主键id,可以将d1.id < d2.id替换为其他唯一标识的比较条件。

方案2:窗口函数实现(高性能)

不需要笛卡尔积连接,适合数据量较大的场景,通过偏移函数取上一条记录的结束日期做判断:

WITH user_discounts AS (
  SELECT 
    user,
    start_date,
    end_date,
    -- 取同用户下按生效日期排序的上一条折扣的结束日期
    LAG(end_date) OVER (PARTITION BY user ORDER BY start_date) AS prev_end
  FROM discounts
)
SELECT DISTINCT user
FROM user_discounts
WHERE start_date < prev_end
ORDER BY user;

业务适配注意事项

  • 如果存在永久生效的折扣(end_date为NULL),可通过COALESCE(end_date, '9999-12-31')将空值替换为极大日期再做判断
  • 若需要同时返回重叠的具体折扣记录,可去掉外层的DISTINCT,保留对应的折扣记录字段即可

内容的提问来源于stack exchange,提问作者Avidan Nisan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 10:27:03