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

如何合并PostgreSQL中间隔不超过5分钟的时间范围?

合并间隔不超过5分钟的PostgreSQL时间范围

可以仅用标准SQL实现该需求,无需自定义聚合函数。核心思路是通过窗口函数标记可合并的范围组,再对每组进行范围合并。

实现代码

WITH sorted_entries AS (
    -- 按合同ID和时间范围起始时间排序
    SELECT 
        contract_id,
        range,
        lower(range) AS range_start,
        upper(range) AS range_end
    FROM time_entries
    ORDER BY contract_id, range_start
),
grouped_entries AS (
    -- 标记合并分组:当前范围与前一范围间隔超过5分钟则新建分组
    SELECT 
        contract_id,
        range,
        range_start,
        range_end,
        SUM(
            CASE 
                WHEN lag(range_end) OVER (PARTITION BY contract_id ORDER BY range_start) + INTERVAL '5 minutes' >= range_start
                THEN 0
                ELSE 1
            END
        ) OVER (PARTITION BY contract_id ORDER BY range_start) AS group_id
    FROM sorted_entries
)
-- 按分组合并时间范围
SELECT 
    contract_id,
    tsrange(MIN(range_start), MAX(range_end)) AS merged_range
FROM grouped_entries
GROUP BY contract_id, group_id
ORDER BY contract_id, merged_range;

结果验证

执行上述SQL后,会得到期望的合并结果:

contract_idmerged_range
1["2022-12-07 09:00:00","2022-12-07 10:30:00")
1["2022-12-07 10:45:00","2022-12-07 11:00:00")

逻辑说明

  1. sorted_entries:将每个合同的时间范围按起始时间排序,确保后续能按顺序判断相邻范围的间隔。
  2. grouped_entries:使用lag()窗口函数获取前一个范围的结束时间,判断当前范围的起始时间是否在前一个范围结束后5分钟内。如果是,则归为同一组;否则新建一个分组。通过SUM()累积分组ID,实现连续可合并范围的分组标记。
  3. 最终聚合:按合同ID和分组ID聚合,用MIN(range_start)和MAX(range_end)生成合并后的时间范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:35:20