I have a table with Case records with CaseId, UserId, Opened date, Closed date etc value.
For reporting I need to have a result table with all users by continuous months with number of case still opened with amount and number of closed case with amount.
CaseID | UserID | Opened On | Closed Date| Value 1 U1 04/01/2020 05/02/2020 500 2 U1 08/01/2020 null 120 3 U3 16/01/2020 null 350 4 U2 21/01/2020 25/01/2020 100 5 U1 25/01/2020 08/04/2020 150 6 U2 05/02/2020 null 790 7 U4 14/02/2020 18/03/2020 190 8 U4 19/02/2020 null 490 9 U1 21/02/2020 27/02/2020 140 10 U2 07/03/2020 17/03/2020 640 11 U1 17/03/2020 12/05/2020 420 12 U3 22/03/2020 null 810 13 U2 05/04/2020 19/05/2020 320 14 U1 18/04/2020 null 180 15 U4 16/05/2020 22/05/2020 210 16 U3 19/05/2020 null 230
Output desired (*values in parenthesis are only for helping)
UserID | Month | Nb case still opened | Total Open | Nb closed case | Total Value closed U1 01 3 (1 ;2 ;5)* 770 0 0 U1 02 2 (2 ;5) 270 2 (1;9) 640 U1 03 3 (2;5;11) 690 0 0 U1 04 3 (2;11;14) 720 1 (5) 150 U1 05 2 (2 ;14) 300 1 (11) 420 U2 01 0 0 1 100 U2 02 1 (6) 790 0 0 U2 03 1 (6) 790 1 640 U2 04 2 (6 ;13) 1100 0 0 U2 05 1 (6) 790 1 (13) 320 U3 01 1 (3) 350 0 0 U3 02 1 (3) 350 0 0 U3 03 2 (6 ;12) 1160 0 0 U3 04 2 (6 ;12) 1160 0 0 U3 05 3 (6 ;12 ;16) 1390 0 0 U4 01 0 0 0 0 U4 02 1 (7 ;8) 680 0 0 U4 03 2 (8) 490 1 190 U4 04 1 (8) 490 0 0 U4 05 1 (8) 490 1 210
I tried to play with CROSS JOIN, OVER (PARTITION) but I didn’t find the solution. Thanks for you help.
Advertisement
Answer
I would first cross join the available year/month and users available to generate the rows. Then, union all
in a subquery can be used to unpivot the opening and closing information (one could possibly use cross apply
too).
The final step is aggregation and window computation:
select u.userID, d.dt year_month, sum(coalesce(sum(no_open - no_closed), 0)) over(partition by u.userID order by d.dt) no_cases_still_open, sum(coalesce(sum(value_open - value_closed), 0)) over(partition by u.userID order by d.dt) value_open, coalesce(sum(no_closed), 0) no_closed, coalesce(sum(value_closed), 0) value_closed from (select distinct datefromparts(year(openedOn), month(openedOn), 1) dt from mytable) d cross join (select distinct userID from mytable) u left join ( select userID, openedOn dt, 1 no_open, value value_open, 0 no_closed, 0 value_closed from mytable union all select userID, closedDate dt, 0, 0, 1, value from mytable ) t on t.userID = u.userID and t.dt >= d.dt and t.dt < dateadd(month, 1, d.dt) group by u.userID, d.dt
userID | year_month | no_cases_still_open | value_open | no_closed | value_closed :----- | :--------- | ------------------: | ---------: | --------: | -----------: U1 | 2020-01-01 | 3 | 770 | 0 | 0 U1 | 2020-02-01 | 2 | 270 | 2 | 640 U1 | 2020-03-01 | 3 | 690 | 0 | 0 U1 | 2020-04-01 | 3 | 720 | 1 | 150 U1 | 2020-05-01 | 2 | 300 | 1 | 420 U2 | 2020-01-01 | 0 | 0 | 1 | 100 U2 | 2020-02-01 | 1 | 790 | 0 | 0 U2 | 2020-03-01 | 1 | 790 | 1 | 640 U2 | 2020-04-01 | 2 | 1110 | 0 | 0 U2 | 2020-05-01 | 1 | 790 | 1 | 320 U3 | 2020-01-01 | 1 | 350 | 0 | 0 U3 | 2020-02-01 | 1 | 350 | 0 | 0 U3 | 2020-03-01 | 2 | 1160 | 0 | 0 U3 | 2020-04-01 | 2 | 1160 | 0 | 0 U3 | 2020-05-01 | 3 | 1390 | 0 | 0 U4 | 2020-01-01 | 0 | 0 | 0 | 0 U4 | 2020-02-01 | 2 | 680 | 0 | 0 U4 | 2020-03-01 | 1 | 490 | 1 | 190 U4 | 2020-04-01 | 2 | 700 | 0 | 0 U4 | 2020-05-01 | 1 | 490 | 1 | 210