Получить счетчик для каждого значения столбца - PullRequest
0 голосов
/ 18 февраля 2020

Вход

Create Table #t1 (CaseId Int, NewValue  char(2),Attribute char(2),TimeStamp datetime)  

insert into #t1 values
(1,      'A',         'X'   ,       '2020-01-01 13:01'),
(1,      'Au',        'WB' ,        '2020-01-01 13:02'),   
(1 ,     'C'  ,       'P'   ,       '2020-01-01 13:03'),
(1 ,     'Ma',        'WB' ,        '2020-01-01 13:04'),
(1 ,     'C'   ,      'D',          '2020-01-01 13:05'), 
(1,      'D'  ,       'E',          '2020-01-01 13:04'),
(2 ,     'M'  ,       'P' ,         '2020-05-01 15:20'),
(2 ,     'X'  ,       'WB' ,        '2020-05-01 15:26'),
(2  ,    'Y' ,        'WB',         '2020-05-01 15:29'), 
(2  ,    'X'  ,       'P'  ,         '2020-05-01 15:31')

Мне нужен вывод, как показано ниже.

CaseId  NewValue    Attribute   TimeStamp   NewColumn   NewColumn   Count
1        A            X         01:00.0         NULL    NULL         0
1        Au           WB        02:00.0         Au-WB   Au-WB        2
1        C            P         03:00.0         Au-WB   Au-WB        2
1        Ma           WB        04:00.0         Ma-WB   Ma-WB        3
1        C            D         05:00.0         Ma-WB   Ma-WB        3
1        D            E         04:00.0         Ma-WB   Ma-WB        3
2        M            P         20:00.0         NULL    NULL         0
2        X            WB        26:00.0         X -WB   X -WB        1
2        Y            WB        29:00.0         Y -WB   Y -WB        2
2        X            P         31:00.0         Y -WB   Y -WB        2

Белка помогла получить все, минус счет. Запрос выглядит следующим образом. Кто-нибудь знает, как получить этот счет?

select  *, wb.NewColumn
from    #t1 t
        outer apply
        (
            select top 1 x.NewValue + '-' + x.Attibute as NewColumn
            from    #t1 x
            where   x.CaseId    = t.CaseId
            and     x.TimeStamp <= t.TimeStamp
            and     x.Attibute  = 'WB'
            order by x.TimeStamp desc
        ) wb

Ответы [ 2 ]

0 голосов
/ 18 февраля 2020

Используя выходные данные запроса, создайте cte и выполните подсчет с помощью функции управления окнами по разделам в caseid, newcolumn следующим образом

with data
 as (
select  *, wb.NewColumn
from    #t1 t
        outer apply
        (
            select top 1 x.NewValue + '-' + x.Attibute as NewColumn
            from    #t1 x
            where   x.CaseId    = t.CaseId
            and     x.TimeStamp <= t.TimeStamp
            and     x.Attibute  = 'WB'
            order by x.TimeStamp desc
        ) wb
    )
select *,count(*) over(partition by caseid,newcolumn) as cnt
 from data
0 голосов
/ 18 февраля 2020

Это выглядит как проблема пробелов и островов, когда новый остров начинается каждый раз, когда встречается запись с Attribute 'WB'.

Если это так, вот один способ решить это с помощью оконных функций:

select 
    caseId,
    newValue,
    attribute,
    timeStamp,
    case when grp > 0
        then first_value(newValue) over(partition by caseId, grp order by timeStamp)
            + '-'
            + first_value(attribute) over(partition by caseId, grp order by timeStamp)
    end newValue,
    case when grp > 0 
        then count(*) over(partition by caseId, grp)
        else 0
    end cnt
from (
    select 
        t.*,
        sum(case when attribute = 'WB' then 1 else 0 end)
            over(partition by caseId order by timeStamp) grp
    from #t1 t
) t
order by caseId, timeStamp

Внутренний запрос делает окно sum() для определения групп: каждый раз attribute 'WB' встречается для данной caseId, новой группы начинается. Затем внешний запрос использует first_value() для восстановления первого значения в группе и выполняет окно count() для вычисления количества записей в группе. Это заключено в условную логику c, поэтому дополнительные столбцы не заполняются до того, как будет встречен первый атрибут 'WB'.

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

caseId | newValue | attribute | timeStamp               | newValue | cnt
-----: | :------- | :-------- | :---------------------- | :------- | --:
     1 | A        | X         | 2020-01-01 13:01:00.000 | <em>null</em>     |   0
     1 | Au       | WB        | 2020-01-01 13:02:00.000 | Au-WB    |   2
     1 | C        | P         | 2020-01-01 13:03:00.000 | Au-WB    |   2
     1 | Ma       | WB        | 2020-01-01 13:04:00.000 | Ma-WB    |   3
     1 | D        | E         | 2020-01-01 13:04:00.000 | Ma-WB    |   3
     1 | C        | D         | 2020-01-01 13:05:00.000 | Ma-WB    |   3
     2 | M        | P         | 2020-05-01 15:20:00.000 | <em>null</em>     |   0
     2 | X        | WB        | 2020-05-01 15:26:00.000 | X -WB    |   1
     2 | Y        | WB        | 2020-05-01 15:29:00.000 | Y -WB    |   2
     2 | X        | P         | 2020-05-01 15:31:00.000 | Y -WB    |   2
...