Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Group over dynamic date ranges

I have a table with IDs, dates and values. I want to always merge the records based on the ID that are within a 90 day window. In the example below, these are the rows marked in the same color.

origin

The end result should look like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

endresult

The entry with the RowId 1 opens the 90 days window for the ID 133741. RowId 2 and 3 are in this window and should therefore be aggregated together with RowId 1.

RowId 4 would be in a 90 day window with 2 and 3, but since it is outside the window for 1, it should no longer be aggregated with them but should be considered as the start of a new 90 day window. Since there are no other entries in this window, it remains as a single line.

The date for line 5 is clearly outside the 90 day window of the other entries and is therefore also aggregated individually. Just like line 6, since this is a different ID.

Below some example code:


create table #Table(RowId int, ID nvarchar(255) , Date date, Amount numeric(19,1));
insert into #Table values


('1','133742',  '2021-07-30',   '1.00'  ),
('2','133742',  '2021-08-05',   '3.00'  ),
('3','133742',  '2021-08-25',   '10.00' ),
('4','133742',  '2021-11-01',   '7.00'  ),
('5','133742',  '2022-08-25',   '11.00' ),
('6','133769',  '2021-11-13',   '9.00'  );

I tried with windowfunctions and CTEs but I could’nt find a way to include all my requirements

>Solution :

With the window function first_value() over() we calculate the distance in days divided by 90 to get the derived Grp

Example

with cte as (
Select *
      ,Grp = datediff(day,first_value(Date) over (partition by id order by date) ,date) / 90
 from #Table
 )
 Select ID 
       ,Date = min(date)
       ,Amount = sum(Amount)
 From  cte
 Group By ID,Grp
 Order by ID,min(date)

Results

ID      Date        Amount
133742  2021-07-30  14.0
133742  2021-11-01  7.0
133742  2022-08-25  11.0
133769  2021-11-13  9.0
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading