如何将两个Datetime列按分钟拆分时间区间(Minute Breakdown)
按分钟拆分时间段的解决方案
根据你的需求,以下是几种主流数据库的实现方案,可将每个不可用时间段拆分成单分钟的记录:
SQL Server 实现
使用递归CTE(公共表表达式)生成每个分钟点:
WITH MinuteCTE AS ( SELECT UnavailableID, UnavailableFrom AS MinuteBreakdown, UnavailableTo FROM UnavailableTime UNION ALL SELECT UnavailableID, DATEADD(MINUTE, 1, MinuteBreakdown), UnavailableTo FROM MinuteCTE WHERE MinuteBreakdown < UnavailableTo ) SELECT UnavailableID, MinuteBreakdown FROM MinuteCTE ORDER BY UnavailableID, MinuteBreakdown OPTION (MAXRECURSION 0); -- 解除递归次数限制,适配较长时间段
MySQL 实现
先创建数字辅助表用于生成分钟间隔,再关联原表查询:
- 创建并填充数字表:
CREATE TABLE IF NOT EXISTS Numbers (n INT PRIMARY KEY); -- 插入基础数字 INSERT INTO Numbers (n) SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9; -- 生成0-999的数字,覆盖大部分场景 INSERT INTO Numbers (n) SELECT n1.n + n2.n*10 + n3.n*100 FROM Numbers n1, Numbers n2, Numbers n3;
- 关联查询拆分时间段:
SELECT ut.UnavailableID, DATE_ADD(ut.UnavailableFrom, INTERVAL num.n MINUTE) AS MinuteBreakdown FROM UnavailableTime ut JOIN Numbers num ON DATE_ADD(ut.UnavailableFrom, INTERVAL num.n MINUTE) <= ut.UnavailableTo ORDER BY ut.UnavailableID, MinuteBreakdown;
PostgreSQL 实现
利用PostgreSQL自带的generate_series函数直接生成分钟序列:
SELECT ut.UnavailableID, generate_series( ut.UnavailableFrom::TIMESTAMP, ut.UnavailableTo::TIMESTAMP, '1 minute'::INTERVAL ) AS MinuteBreakdown FROM UnavailableTime ut ORDER BY ut.UnavailableID, MinuteBreakdown;
内容的提问来源于stack exchange,提问作者Laura Bullard
相关产品推荐
相关产品推荐

