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

TSQL查询两段日期间所有日期 解决重复记录与性能问题

解决方案

实现思路

  • 先对原表的[WkStart]和[WkEnd]做去重处理,同一周区间只保留1条,从源头避免重复生成日期
  • 采用数字理货表(Tally Table)生成连续日期,相比递归CTE无递归栈开销,大数据量下性能提升非常明显
  • 通过EXISTS判断当前生成的日期是否在原表的[MyDate]字段中存在,直接得到正确的bit值,不需要额外去重

实现代码

-- 生成0~1000的数字序列,足够覆盖所有周区间的天数需求,可根据实际场景扩展上限
WITH Tally (n) AS
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1
    FROM sys.all_columns ac1 CROSS JOIN sys.all_columns ac2
),
-- 第一步:去重所有唯一的周区间,避免同一周重复生成日期
DistinctWeeks AS
(
    SELECT DISTINCT WkStart, WkEnd
    FROM @Dates
),
-- 第二步:生成每个周区间内的所有连续日期
AllWeekDates AS
(
    SELECT DATEADD(DAY, t.n, dw.WkStart) AS DateVal
    FROM DistinctWeeks dw
    JOIN Tally t ON t.n <= DATEDIFF(DAY, dw.WkStart, dw.WkEnd)
)
-- 第三步:判断日期是否为MyDate,得到最终结果
SELECT 
    awd.DateVal,
    CAST(CASE WHEN EXISTS (SELECT 1 FROM @Dates d WHERE d.MyDate = awd.DateVal) THEN 1 ELSE 0 END AS BIT) AS isMyDate
FROM AllWeekDates awd
ORDER BY awd.DateVal

提示:如果你的数据库中有预先构建的永久数字理货表,直接替换上面的Tally CTE部分,性能会进一步提升。

方案优势

  • 解决了原方案的重复日期问题:周区间先去重,同一周只会生成一次完整的日期序列
  • 性能优异:理货表采用系统表笛卡尔积生成数字序列,无需递归,即使千万级数据量也能高效运行
  • 逻辑简洁:通过EXISTS判断bit值,自动处理同一周存在多个MyDate的场景,只要日期匹配任意一个MyDate就返回1,完全符合需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:45:01