Заполните пропущенные даты и проблему группировки - PullRequest
1 голос
/ 01 мая 2020

У меня есть таблица с записями дел с CaseId, UserId, Открытой датой, Закрытой датой и значением c.

Для создания отчетов мне нужна таблица результатов со всеми пользователями по непрерывным месяцам с числом кейс все еще открыт с суммой, а номер закрытого кейса с суммой.

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

Требуется вывод (* значения в скобках предназначены только для помощи)

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

Я пытался играть с CROSS JOIN , НАД (РАЗДЕЛ), но я не нашел решения. Спасибо за помощь.

1 Ответ

1 голос
/ 01 мая 2020

Сначала я присоединюсь к доступному году / месяцу и пользователям, которые смогут сгенерировать строки. Затем, union all в подзапросе может использоваться для отмены открытия и закрытия информации (возможно, можно также использовать cross apply).

Последний шаг - агрегация и вычисление окна:

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 

Демонстрация на DB Fiddle :

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