-1

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
GMB
  • 216,147
  • 25
  • 84
  • 135

2 Answers2

1

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).

GMB
  • 216,147
  • 25
  • 84
  • 135
0

You can use window funtions for that

First wie need a group to group by, which the frist both CTEs will provide

WITH CTE As(
SELECT
     Row, Name, Flag, Days
  , CASE WHEN Flag <> LAG(Flag) OVER(PARTITION BY Name ORDEr By row)
  OR LAG(Flag) OVER(PARTITION BY Name ORDEr By row) IS NULL THEN 1 ELSe 0 ENd rnk
FROM tab1),
CTE2 AS (SELECT
Row, Name, Flag, Days, SUM(rnk) OVER(ORDER BY row) rnk
FROM CTE)
SELECT 
    Row, Name, Flag, Days
FROM CTE2 WHERE Flag = 0
UNION ALL
SELECT 
    MIN(Row), Name, Flag, SUM(Days) as Days
FROM CTE2 WHERE Flag = 1
GROUP BY Name,Flag, rnk
ORDER By row
ROW NAME FLAG DAYS
1 Kyle 0 12
2 Kyle 0 2
3 Kyle 1 20
6 Kyle 0 1
7 Kyle 1 2

fiddle

nbk
  • 45,398
  • 8
  • 30
  • 47