SQL суммы или минимумы-максимумы внутри однотипных повторяющихся подгрупп

SQL суммы или минимумы-максимумы внутри однотипных повторяющихся групп разделяемых другими группами

Или в моем практическом случае была задача на «схлопывание» однотипных диапазонов по времени, минимум и максимум в подгруппе.


**Schema (PostgreSQL v11)**
    
    create table transactions (id int, type int, sum decimal);
    
    insert into transactions
    (id, type, sum)
    VALUES
    (1, 1, 100),(2, 1, 101),
    (3, 2, 200),(4, 2, 201),
    (5, 3, 300),(6, 3, 301),
    (7, 3, 302),(8, 2, 500),
    (9, 2, 510),(10, 1, 20);
        
---
**Query #1**

    with 
    t1 as (
    	select *, lead(type) over (order by id) rn1, lag(type) over (order by id) rn2 from transactions
    ) 
    ,t2 as (
      select t1.*, 
        sum(case when type=rn1 and (rn1!=rn2 or rn2 is null) or (rn1 is null and type!=rn2) then 1 else 0 end) over(order by id) sg
        from t1
     )
    select min(id) first_id_in_group, type, sum(t2.sum) from t2
     group by sg, type
     order by 1;

| first_id_in_group | type | sum  |
| ----------------- | ---- | ---- |
| 1                 | 1    | 201  |
| 3                 | 2    | 401  |
| 5                 | 3    | 903  |
| 8                 | 2    | 1010 |
| 10                | 1    | 20   |
---

С помощью условий находим начала интервалов, обозначаем их 1, последующие записи в группе 0

case when type=rn1 and (rn1!=rn2 or rn2 is null) or (rn1 is null and type!=rn2) then 1 else 0 end

Кумулятивно суммируем и получаем номера групп.

sum() over(order by id)

Ну а дальше всё как обычно.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *