SQL Server
Data:
Row | Type | Start Date | End Date | Dollars
------------------------------------------
1 | 1 | 01/01/2017 | 01/05/2017 | 10
2 | 1 | 01/08/2017 | 01/12/2017 | 10
3 | 1 | 01/17/2017 | 01/19/2017 | 10
4 | 1 | 01/28/2017 | 02/10/2017 | 10
5 | 1 | 02/20/2017 | 03/10/2017 | 10
6 | 2 | 10/01/2017 | 10/03/2017 | 10
7 | 2 | 10/20/2017 | 10/23/2017 | 10
8 | 2 | 10/25/2017 | 10/29/2017 | 10
Within types, I need to group consecutive date periods as long as they are separated by less than 7 days, summing the dollars and the total gap days within each group.
Intermediate Table:
Row | Type | Start Date | End Date | Dollars | Grouping | GapDays
------------------------------------------
1 | 1 | 01/01/2017 | 01/05/2017 | 10 | 1 | null
2 | 1 | 01/08/2017 | 01/12/2017 | 10 | 1 | 3
3 | 1 | 01/17/2017 | 01/19/2017 | 10 | 1 | 5
4 | 1 | 01/28/2017 | 02/10/2017 | 10 | 2 | 9
5 | 1 | 02/20/2017 | 03/10/2017 | 10 | 3 | 10
6 | 2 | 10/01/2017 | 10/03/2017 | 10 | 1 | null
7 | 2 | 10/20/2017 | 10/23/2017 | 10 | 2 | 17
8 | 2 | 10/25/2017 | 10/29/2017 | 10 | 2 | 2
Result:
----------------------------------------------------
Type | Start Date | End Date | Dollars | GapDays
----------------------------------------------------
1 | 01/01/2017 | 01/19/2017 | 30 | 8
1 | 01/28/2017 | 02/10/2017 | 10 | 0
1 | 02/20/2017 | 03/10/2017 | 10 | 0
2 | 10/01/2017 | 10/03/2017 | 10 | 0
2 | 10/20/2017 | 10/29/2017 | 20 | 2
Solution: Use binary grouping for "consecutive" date criteria (in this case < 7 days) and then use that grouping in a sum over with rows unbounded preceding
with cte as (
select
*,
COALESCE(DATEDIFF(dd, LAG(EndDate, 1, NULL) OVER (PARTITION BY [Type] ORDER BY StartDate), StartDate),0) AS GapDays
from
#data
),
cte2 as (
select
*,
case when GapDays < 7 then 0 else 1 end as group1
from
cte
),
cte3 as (
select
*,
sum(group1) over (partition by [type] order by startDate, endDate rows unbounded preceding) as group2
from
cte2
)
select
[TYPE],
MIN(StartDate) AS StartDate,
MAX(EndDate) AS EndDate,
SUM(Dollars) AS Dollars,
SUM(CASE WHEN GapDays > 7 THEN 0 ELSE GapDays END) AS GapDays
from
cte3
group by
[Type], group2