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

如何为窗口(Partition)内的Start-Stop区间标记统一ID?

问题描述

我们有按item_id分区、按time排序的事件数据,示例如下:

item_id    state    time
---------- -------- -----
a1         start    t1
a1         stall    t2
a1         restart  t3
a1         stall    t4
a1         restart  t5
a1         stop     t6

a2         start    t9
a2         stop     t10
a2         start    t11
a2         stop     t12

需要将每个item_id下的事件划分为多个区间:每个区间以start为起点,以下一个stop为终点;若后续无stop,则以start之后的最后一条记录为终点。目前已能为start记录生成唯一的interval_id,但无法为区间内其他记录填充相同的ID。

解决方案

无需依赖临时表,直接用窗口函数即可完成interval_id的批量填充,核心逻辑是通过累计统计start状态的出现次数来标记区间。

基础实现(分区内唯一ID)

SELECT
    item_id,
    state,
    time,
    -- 累计统计当前行及之前的start数量,作为区间ID
    SUM(CASE WHEN state = 'start' THEN 1 ELSE 0 END) 
        OVER (PARTITION BY item_id ORDER BY time ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS interval_id
FROM
    your_table_name
ORDER BY
    item_id, time;

执行后结果如下,每个区间内的所有记录会共享同一interval_id:

item_id    state    time  interval_id
---------- -------- ----- ------------
a1         start    t1    1
a1         stall    t2    1
a1         restart  t3    1
a1         stall    t4    1
a1         restart  t5    1
a1         stop     t6    1

a2         start    t9    1
a2         stop     t10   1
a2         start    t11   2
a2         stop     t12   2

进阶实现(全局唯一ID)

如果需要像示例中那样生成全局唯一的interval_id(如a2的第一个区间为2、第二个为3),可以在基础结果上叠加全局排序:

WITH interval_data AS (
    SELECT
        item_id,
        state,
        time,
        SUM(CASE WHEN state = 'start' THEN 1 ELSE 0 END) 
            OVER (PARTITION BY item_id ORDER BY time) AS local_interval_id
    FROM your_table_name
)
SELECT
    item_id,
    state,
    time,
    DENSE_RANK() OVER (ORDER BY item_id, local_interval_id) AS interval_id
FROM interval_data
ORDER BY item_id, time;

该版本会生成全局唯一的interval_id,完全匹配你示例中的编号规则。


内容的提问来源于stack exchange,提问作者Kirk Fleming

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 22:32:20