How can I summarize the days Kyle has on this table using a flag field?
Row | Name | Flag | Days |
---|---|---|---|
1 | Kyle | 0 | 12 |
2 | Kyle | 0 | 02 |
3 | Kyle | 1 | 01 |
4 | Kyle | 1 | 18 |
5 | Kyle | 1 | 01 |
6 | Kyle | 0 | 01 |
7 | Kyle | 1 | 01 |
8 | Kyle | 1 | 01 |
I want this result:
Row | Name | Flag | Days |
---|---|---|---|
1 | Kyle | 0 | 12 |
2 | Kyle | 0 | 02 |
3 | Kyle | 1 | 20 |
6 | Kyle | 0 | 01 |
7 | Kyle | 1 | 02 |
This reads like a gaps-and-island problem. If I follow this correctly, we can identify "adjacent" rows with the difference between row numbers, then aggregate islands whose flag is enabled:
select min(row) as row, name, flag, sum(days) as days
from (
select t.*,
row_number() over(partition by name order by row) rn1,
row_number() over(partition by name, flag order by row) rn2
from mytable t
) t
group by name, flag,
case when flag = 1 then rn1 - rn2 else row end
order by 1
Demo on DB Fiddle (credits to nbk for creating the use case).