我使用下面的代码来查找 24 小时内的空闲时间。代码运行良好,但仅显示某些时间之间的间隙。 例如,如果我们的繁忙时间是 19:00 到 19:40,另一个繁忙时间是 20:30 到 21:00,我们需要显示以下结果:
free_time_start free_time_end
00:00:00 19:40:00
19:40:00 20:30:00
21:00:00 24:00:00
但结果是:
19:40:00 20:30:00
表示结果仅显示繁忙时间之间的时间。从一天开始或一天结束时,不要在它们之前和之后显示。
我的代码:
SELECT
last_time + INTERVAL 0 MINUTE AS free_time_start,
time - INTERVAL 0 MINUTE AS free_time_end
FROM (
SELECT
sc.*,lag(time+ INTERVAL perclocko MINUTE ) OVER (PARTITION BY courses_id ORDER BY time) AS last_time
FROM
students_courses sc
) s
WHERE last_time < time;
注意:每个时钟是每节课的持续时间。
我尝试向查询添加假行,如下所示:
Union 0,0,0,0,'00:00:00',30,1
但这行不通
演示示例:
CREATE TABLE timeslots (
time_start TIME,
time_end TIME,
CHECK ('00:00:00' <= time_start),
CHECK (time_start < time_end),
CHECK (time_end <= '24:00:00')
);
INSERT INTO timeslots VALUES
('19:00', '19:40'), ('20:30', '21:00');
SELECT * FROM timeslots;
时间_开始 | 时间结束 |
---|---|
19:00:00 | 19:40:00 |
20:30:00 | 21:00:00 |
WITH
cte1 AS (
SELECT '00:00:00' slot, 1 weight
UNION ALL
SELECT '24:00:00', -1
UNION ALL
SELECT time_start, -1 FROM timeslots
UNION ALL
SELECT time_end, 1 FROM timeslots
),
cte2 AS (
SELECT slot, SUM(weight) OVER (ORDER BY slot) cum_sum
FROM cte1
),
cte3 AS (
SELECT slot, SUM(cum_sum) OVER (ORDER BY slot) cum_sum
FROM cte2
)
SELECT MIN(slot) free_time_start,
MAX(slot) free_time_end
FROM cte3
GROUP BY cum_sum;
空闲时间开始 | 空闲时间结束 |
---|---|
00:00:00 | 19:00:00 |
19:40:00 | 20:30:00 |
21:00:00 | 24:00:00 |
查询假设没有重叠的时隙。