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

基于SQL Islands and Gaps技术查询车辆可用时段

识别车辆预订会话中的可用时段(基于Gaps and Islands技术)

我们正尝试简化公司内部的车辆预订流程。目前采用1小时时段预订模式,用户若需全日用车,得重复多次操作。现在计划设置车辆可用周期,允许用户选择任意时长预订,所以需要借助SQL Gaps and Islands技术,从预订会话和预订记录里找出车辆未被预订的可用时段。

示例表结构与测试数据

DECLARE @BookingSession TABLE
(
    id_BookingSession INT
    ,SessionStart DATETIME
    ,SessionEnd DATETIME
);

INSERT INTO @BookingSession (id_BookingSession,SessionStart,SessionEnd)
VALUES
(
    1,'20260507 09:00','20260507 17:00'
);

DECLARE @Bookings TABLE
(
    id_BookingSession INT
    ,id_BookingSession_Slot INT
    ,TimeFrom DATETIME
    ,TimeUntil DATETIME
);

--生成部分预订记录
INSERT INTO @Bookings (id_BookingSession,id_BookingSession_Slot,TimeFrom,TimeUntil) 
VALUES
(1,90,'20260507 10:05','20260507 10:45')  -- 40分钟预订
,(1,91,'20260507 11:05','20260507 11:30') -- 25分钟预订
,(1,93,'20260507 11:30','20260507 12:30') -- 60分钟预订(与上一条无间隔);

SELECT * FROM @BookingSession;
SELECT * FROM @bookings;

期望输出

Result
09:00 - 10:05 Available
10:45 - 11:05 Available
12:30 - 17:00 Available

解决方案

利用Gaps and Islands思路,我们可以把预订会话的时间范围和已有的预订记录整合,定位出所有未被占用的时段:

WITH BookingIntervals AS (
    -- 会话开始到第一个预订的间隔
    SELECT 
        bs.id_BookingSession,
        bs.SessionStart AS IntervalStart,
        MIN(b.TimeFrom) AS IntervalEnd
    FROM @BookingSession bs
    LEFT JOIN @Bookings b ON bs.id_BookingSession = b.id_BookingSession
    GROUP BY bs.id_BookingSession, bs.SessionStart

    UNION ALL

    -- 相邻两个预订之间的间隔
    SELECT 
        b1.id_BookingSession,
        b1.TimeUntil AS IntervalStart,
        MIN(b2.TimeFrom) AS IntervalEnd
    FROM @Bookings b1
    JOIN @Bookings b2 ON b1.id_BookingSession = b2.id_BookingSession 
        AND b2.TimeFrom > b1.TimeUntil
    GROUP BY b1.id_BookingSession, b1.TimeUntil

    UNION ALL

    -- 最后一个预订结束到会话结束的间隔
    SELECT 
        bs.id_BookingSession,
        MAX(b.TimeUntil) AS IntervalStart,
        bs.SessionEnd AS IntervalEnd
    FROM @BookingSession bs
    LEFT JOIN @Bookings b ON bs.id_BookingSession = b.id_BookingSession
    GROUP BY bs.id_BookingSession, bs.SessionEnd
)
-- 筛选有效时段并格式化输出
SELECT 
    FORMAT(IntervalStart, 'HH:mm') + ' - ' + FORMAT(IntervalEnd, 'HH:mm') + ' Available' AS Result
FROM BookingIntervals
WHERE IntervalStart < IntervalEnd
ORDER BY IntervalStart;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 23:54:53