Как записать значение на основе комбинации других значений - PullRequest
2 голосов
/ 12 марта 2019

Пример данных выглядит так:

enter image description here

цель:

Если у нас одинаковые ControlNo и ActionDate (включая время) и комбинация Action = 'Changed status' и 'Print Quote', затем 'Print Quote'

Если у нас одинаковые ControlNo и ActionDate (включая время) и комбинация Action = 'Changed status' и 'Reason for quote', затем 'Changed Status'

Пример запроса:

declare @TempTable table (
    Name varchar(50), 
    ControlNo int, 
    PolicyNumber varchar(50), 
    Action varchar(max), 
    ActionDate datetime
)


insert into @TempTable values 
    ('Jim',54321, NULL, 'Changed status','2019-01-29 09:56:12.820' ),
    ('Jim',54321, NULL, 'Print Quote','2019-01-29 09:56:12.820' ),
    ('Brian',12345, NULL, 'Changed status','2019-02-15 11:18:07.356' ),
    ('Brian',12345, NULL, 'Reason for quote','2019-02-15 11:18:07.356') 

select * from @TempTable

Желаемый результат должен выглядеть так: enter image description here

Я пытался добиться этого с помощью:

select   
    name, 
    ControlNo, 
    PolicyNumber, 
    case 
        when  action in( 'Changed status','Print Quote') then 'Print Quote'
        when action in ('Changed status', 'Reason for quote') then 'Changed Status'
        else Action end as Action
from @TempTable
group by 
    name, 
    ControlNo, 
    PolicyNumber, 
    Action

Но это не дает мне правильного результата:

enter image description here

Ответы [ 2 ]

3 голосов
/ 12 марта 2019

Этого можно достичь, не используя подзапрос, используя условное агрегирование для реализации логики:

SELECT
    Name, 
    ControlNo, 
    PolicyNumber,
    ActionDate,
    CASE 
        WHEN MAX(CASE WHEN Action = 'Changed status'  THEN 1 END) = 1 
        AND  MAX(CASE WHEN Action = 'Print Quote'     THEN 1 END) = 1
            THEN 'Print Quote'
        WHEN MAX(CASE WHEN Action = 'Changed status'   THEN 1 END) = 1 
        AND  MAX(CASE WHEN Action = 'Reason for quote' THEN 1 END) = 1
            THEN 'Changed Status'
        ELSE MAX(Action)
    END AS Action
FROM @TempTable
GROUP BY 
    Name, 
    ControlNo, 
    PolicyNumber, 
    ActionDate

Примечание: по моему мнению, результаты имеют больше смысла с включенным столбцом ActionDate (поскольку он является частью неагрегированных столбцов).

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

Name  | ControlNo | PolicyNumber | ActionDate          | Action        
:---- | --------: | :----------- | :------------------ | :-------------
Brian |     12345 | <em>null</em>         | 15/02/2019 11:18:07 | Changed Status
Jim   |     54321 | <em>null</em>         | 29/01/2019 09:56:12 | Print Quote   
1 голос
/ 12 марта 2019

Обратите внимание, что условие «IN» работает как «ИЛИ».

Код, который может помочь:

SELECT a.Name,a.ControlNo,a.PolicyNumber,a.Action,a.ActionDate
FROM (
    SELECT t.Name,t.ControlNo,t.PolicyNumber
        ,CASE 
            WHEN t2.Action = 'Print Quote' THEN 'Print Quote'
            WHEN t2.Action = 'Reason for quote' THEN 'Changed status'
        END AS [Action]
        ,t.ActionDate
    FROM @TempTable t
    LEFT JOIN @TempTable t2 ON t2.ControlNo = t.ControlNo AND t2.ActionDate = t.ActionDate AND t2.Action <> t.Action
    WHERE t.Action = 'Changed status'
) a
GROUP BY a.Name,a.ControlNo,a.PolicyNumber,a.Action,a.ActionDate
;
...