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

在TSQL中跨天查询时段:周内服务时段可用性校验求助

搞定周历时段可用性校验(含跨天场景)

没问题,我来帮你解决这个周历时段校验的问题——尤其是跨天的场景,这确实是这类只存星期规则的表容易踩的坑。你的#Calendar表只记录重复的周时段(没有具体日期),跨天的服务(比如周一19:00到周二07:00)其实是覆盖了两个连续星期几的时间段,所以校验时得分场景处理。

核心逻辑拆解

我们要判断目标校验时段是否和表中已有的服务时段重叠。重叠分两种情况:

  • 同天服务:服务的星期和目标时段星期一致,直接判断时间区间是否重叠。
  • 跨天服务:服务的HourStart > HourEnd(比如19:00到07:00),这意味着服务覆盖了当前星期的HourStart到当天结束,加上下一个星期的凌晨到HourEnd。

可直接用的SQL方案

假设我们要校验的目标时段用这几个参数定义(你可以根据实际情况替换):

  • @CheckStartDay:目标时段开始的星期几(和表中DayWeek格式一致,比如1=周一)
  • @CheckStartTime:目标时段开始时间(TIME类型)
  • @CheckEndDay:目标时段结束的星期几
  • @CheckEndTime:目标时段结束时间(TIME类型)

第一步:先定义测试参数(示例)

-- 比如我们要校验周一20点到周二6点是否可用
DECLARE @CheckStartDay INT = 1, @CheckStartTime TIME = '20:00:00';
DECLARE @CheckEndDay INT = 2, @CheckEndTime TIME = '06:00:00';

第二步:执行校验查询

-- 检查是否存在重叠的服务时段
IF EXISTS (
    SELECT 1
    FROM #Calendar c
    WHERE
        -- 场景1:服务是同天时段(没跨天)
        (c.HourStart <= c.HourEnd 
         AND (
             -- 目标时段不跨天:服务星期和目标一致,且时间重叠
             (@CheckStartDay = @CheckEndDay 
              AND c.DayWeek = @CheckStartDay
              AND c.HourStart < @CheckEndTime 
              AND c.HourEnd > @CheckStartTime)
             -- 目标时段跨天:服务在目标的星期区间内,且要么覆盖全天,要么和首尾时间重叠
             OR (@CheckStartDay < @CheckEndDay 
                 AND c.DayWeek BETWEEN @CheckStartDay AND @CheckEndDay
                 AND (
                     -- 服务在中间星期(比如目标是周一到周三,服务在周二),直接算重叠
                     (c.DayWeek > @CheckStartDay AND c.DayWeek < @CheckEndDay)
                     -- 服务在起始星期,结束时间晚于目标开始时间
                     OR (c.DayWeek = @CheckStartDay AND c.HourEnd > @CheckStartTime)
                     -- 服务在结束星期,开始时间早于目标结束时间
                     OR (c.DayWeek = @CheckEndDay AND c.HourStart < @CheckEndTime)
                 ))
         ))
        OR
        -- 场景2:服务是跨天时段(比如19:00到07:00)
        (c.HourStart > c.HourEnd
         AND (
             -- 服务跨天的区间和目标时段有重叠
             (
                 -- 服务起始星期在目标区间内,或者跨到的下一个星期在目标区间内
                 (c.DayWeek BETWEEN @CheckStartDay AND @CheckEndDay)
                 OR (c.DayWeek + 1 BETWEEN @CheckStartDay AND @CheckEndDay)
                 -- 处理跨周末的情况(比如目标是周日到周一,DayWeek 7到1)
                 OR (@CheckStartDay > @CheckEndDay 
                     AND (c.DayWeek >= @CheckStartDay OR c.DayWeek + 1 <= @CheckEndDay))
             )
             AND (
                 -- 服务起始星期和目标起始星期相同:服务开始时间早于目标结束时间
                 (c.DayWeek = @CheckStartDay AND c.HourStart < @CheckEndTime)
                 -- 服务跨到的星期和目标结束星期相同:服务结束时间晚于目标开始时间
                 OR (c.DayWeek + 1 = @CheckEndDay AND c.HourEnd > @CheckStartTime)
                 -- 服务完全覆盖目标的中间星期
                 OR (c.DayWeek > @CheckStartDay AND c.DayWeek + 1 < @CheckEndDay)
             )
         ))
)
BEGIN
    PRINT '❌ 该时段不可用,已有服务占用';
END
ELSE
BEGIN
    PRINT '✅ 该时段可用';
END

用你的示例数据测试

把你的示例表数据导入后,测试几个场景:

  1. 校验周一20:00到周二06:00:会检测到和Make a Cake重叠,输出「不可用」
  2. 校验周二07:00到周二18:00:没有对应的服务时段,输出「可用」
  3. 校验周一18:00到周一20:00:和Make a cookie(周一07-19)、Make a Cake(周一19-07)都重叠,输出「不可用」

小提示

  • 如果你的DayWeek规则是周日=1、周一=2这类,只需要调整参数的星期数值就行,逻辑不用改。
  • 可以把这段逻辑封装成SQL函数,以后调用更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:05:33