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

如何在PostgreSQL中检测连续活动时段并聚合数据

按连续日期时段聚合数据的SQL解决方案

你的核心需求是将连续日期的记录划分为同一时段(period),再按时段聚合求和。原SQL的问题在于累加逻辑错误,导致无法正确分段,以下是修正方案:

1. 生成中间时段标记结果

使用以下SQL可以得到你期望的中间输出:

SELECT 
    t, 
    data,
    SUM(is_new_period) OVER (ORDER BY t) AS period
FROM (
    SELECT 
        t, 
        data,
        -- 标记是否为新时段的起始行
        CASE 
            WHEN LAG(t) OVER (ORDER BY t) IS NULL 
                OR t - LAG(t) OVER (ORDER BY t) > 1 
            THEN 1 
            ELSE 0 
        END AS is_new_period
    FROM t_series
) AS x;

逻辑说明

  • 子查询中通过LAG(t)获取上一条记录的日期,判断当前记录是否属于新时段:
    • 第一条记录无前置日期,直接标记为新时段起始(1)
    • 当前日期与上一条日期间隔超过1天时,标记为新时段起始(1)
    • 其余连续日期的记录标记为0
  • 外层通过累加这些起始标记,生成连续的时段编号(period),相同连续日期的记录会得到同一个period值。

2. 生成最终聚合结果

基于上述中间结果,按period分组求和即可得到最终输出:

SELECT 
    period,
    SUM(data) AS sum
FROM (
    SELECT 
        t, 
        data,
        SUM(is_new_period) OVER (ORDER BY t) AS period
    FROM (
        SELECT 
            t, 
            data,
            CASE 
                WHEN LAG(t) OVER (ORDER BY t) IS NULL 
                    OR t - LAG(t) OVER (ORDER BY t) > 1 
                THEN 1 
                ELSE 0 
            END AS is_new_period
        FROM t_series
    ) AS x
) AS y
GROUP BY period
ORDER BY period;

你也可以简化嵌套层级,直接在聚合时计算period:

SELECT 
    period,
    SUM(data) AS sum
FROM (
    SELECT 
        data,
        SUM(
            CASE 
                WHEN LAG(t) OVER (ORDER BY t) IS NULL 
                    OR t - LAG(t) OVER (ORDER BY t) > 1 
                THEN 1 
                ELSE 0 
            END
        ) OVER (ORDER BY t) AS period
    FROM t_series
) AS x
GROUP BY period
ORDER BY period;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 07:45:26