Oracle SQL - 仅按附近的相同记录分组

Oracle SQL - group only by nearby same records

我需要对值列相同的记录的延迟时间求和(以秒为单位)。问题是我只需要将它们按相同的块分组而不是全部放在一起。例如,对于下面的数据,我需要对值 3 的 3 条记录求和,并分别对更下方的 2 条记录求和,而不是对值 4 的记录求和,因为它们不在一起。有办法吗?

ID     Value   Timestamp       Delay(s)
166549627   4   19-OCT-21 11:00:19  11.4
166549450   8   19-OCT-21 11:00:27  7.5
166549446   3   19-OCT-21 11:00:34  7.1
166549625   3   19-OCT-21 11:00:45  10.9
166549631   3   19-OCT-21 11:00:58  13.3
166550549   3   19-OCT-21 11:01:03  4.5
166549618   7   19-OCT-21 11:01:14  8.8
166549627   4   19-OCT-21 11:01:23  11.4
166550549   3   19-OCT-21 11:01:45  4.5
166550549   3   19-OCT-21 11:01:59  4.5

如果您想使用 PL/SQL,您可以遍历按时间戳排序的所有记录。

只要记住最后一个值,如果与当前值相同则求和。如果没有,就将总和保存到其他地方并继续。

您也可以将其编写为流水线函数,以使用查询访问数据。

declare
    l_sum      number := 0;
    l_last_val number;
begin
    for rec in (select * from your_table order by timestamp) loop
        if l_last_val = rec.value then
            l_sum := l_sum + rec.delay;
            continue;
        elsif l_last_val is not null then
            dbms_output.put_line('value: ' || l_last_val || ' sum: ' || l_sum); -- save last_val and sum
        end if;
            l_last_val := rec.val;
            l_sum      := rec.delay;
    end loop;
    dbms_output.put_line('value: ' || l_last_val || ' sum: ' || l_sum); -- save last_val and sum
end;

您甚至不需要为此目的使用 plsql。只有 SQL 就足够了。 下面的解决方案使用 递归通用 table 表达式 (CTE) 技术根据值列和时间戳列创建子组。

with ranked_rows (ID, VALUE, TIMESTAMP, DELAY, RNB) as (
select ID, VALUE, TIMESTAMP, DELAY, row_number()over(order by TIMESTAMP) rnb
from YourTable
)
, cte (ID, VALUE, TIMESTAMP, DELAY, RNB, grp) as (
select ID, VALUE, TIMESTAMP, DELAY, RNB, 1 grp
from ranked_rows
where rnb = 1
union all
select t.ID, t.VALUE, t.TIMESTAMP, t.DELAY, t.RNB, case when c.VALUE = t.VALUE then c.grp else c.grp + 1 end
from ranked_rows t
join cte c on c.rnb + 1 = t.rnb
)
select VALUE, sum(DELAY) sum_consecutive_DELAY, min(TIMESTAMP) min_TIMESTAMP, max(TIMESTAMP) max_TIMESTAMP, count(*)nb_rows
from cte
group by VALUE, GRP
order by min_TIMESTAMP
;

demo