假设有下表:
CREATE TABLE time_interval (
id SERIAL PRIMARY KEY,
start_time TIMESTAMP NOT NULL,
end_time TIMESTAMP
);
样本数据:
INSERT INTO time_interval (start_time, end_time) VALUES
('2024-02-10 01:30:00', null), -- pending
('2024-02-10 03:00:00', null), -- pending
('2024-02-10 07:00:00', '2024-02-10 10:30:00'),
('2024-02-10 09:00:00', '2024-02-10 12:00:00'),
('2024-02-10 11:30:00', '2024-02-10 15:00:00'),
('2024-02-10 13:30:00', '2024-02-10 17:30:00'),
('2024-02-10 16:00:00', '2024-02-10 20:00:00'),
('2024-02-10 18:30:00', '2024-02-10 22:00:00'),
('2024-02-10 21:00:00', '2024-02-10 23:30:00');
查询:
给我
2024-02-10 10:00:00 - 2024-02-10 17:00:00
之间的所有间隔,包括重叠的
预期结果:
('2024-02-10 01:30:00', null)
('2024-02-10 03:00:00', null)
('2024-02-10 07:00:00', '2024-02-10 10:30:00')
('2024-02-10 09:00:00', '2024-02-10 12:00:00')
('2024-02-10 11:30:00', '2024-02-10 15:00:00')
('2024-02-10 13:30:00', '2024-02-10 17:30:00')
('2024-02-10 16:00:00', '2024-02-10 20:00:00')
我试图使用 union 来分割待处理和未处理之间的逻辑,但我不确定。
这是简单的版本:
SELECT *
FROM time_interval
WHERE start_time < '2024-02-10 17:00:00'
AND (end_time is null or end_time > '2024-02-10 10:00:00');
结果很好,但问题是...有那么简单吗?我错过了什么吗?有人看到我应该包括的其他极端情况吗?
您可以使用条件
(StartA <= EndB) and (EndA >= StartB)
来确定重叠日期。在您的情况下,开始和结束时间可能为空:
SELECT *
FROM time_interval
WHERE (start_time <= '2024-02-10 17:00:00' OR start_time IS NULL)
AND ('2024-02-10 10:00:00' <= end_time OR end_time IS NULL);
更多详细信息请参见:确定两个日期范围是否重叠
您可以检查开始时间或结束时间是否在所述间隔的开始点和结束点之间或间隔的开始点在开始时间和结束时间之间或间隔的结束点在开始时间和结束时间之间:
SELECT *
FROM time_interval
WHERE (start_time BETWEEN '2024-02-10 17:00:00' AND '2024-02-10 10:00:00') OR
(end_time BETWEEN '2024-02-10 17:00:00' AND '2024-02-10 10:00:00') OR
('2024-02-10 17:00:00' BETWEEN start_time AND end_time) OR
('2024-02-10 10:00:00' BETWEEN start_time AND end_time) OR