SQL: выберите 2 последовательных строки с условиями - PullRequest
0 голосов
/ 08 сентября 2018

У меня есть табличное событие с 3 столбцами, и я хотел бы выбрать две последовательные строки одного и того же идентификатора дела с определенными критериями (правилами) следующим образом. У меня есть около 5k + различных идентификаторов дел для выбора на основе заданных критериев, и ниже приведен только пример 2 идентификаторов дел. У меня есть часть кода, чтобы попытаться, однако, застрял, потому что я не знаю, как выбрать обе строки, если выполняются условия.

Правила:

  • Если D1 следует за D3, ТО Выберите обе строки
  • Если D1 следует за D4, ТО ВЫБЕРИТЕ обе строки
  • Если D1 следует за D1, ТО ВЫБЕРИТЕ обе строки
  • Если D3 следует за D3, ТО ВЫБЕРИТЕ обе строки
  • Если D3 следует за D2, ТО ВЫБЕРИТЕ обе строки
  • Если D3 следует за D1, ТО ВЫБЕРИТЕ обе строки
  • Остальное Не выбирайте

Событие стола:

caseID         D         Timestamp
-----------------------------------
   1           D1           T1
   1           D2           T2
   1           D3           T3
   1           D1           T4
   1           D3           T5
   1           D2           T6
   1           D1           T7
   1           D2           T8
   1           D4           T9
   2           D2           T1
   2           D1           T2
   2           D2           T3
   2           D3           T4
   2           D1           T5
   2           D4           T6
   2           D5           T7

Ожидаемый результат:

caseID         D         Timestamp
----------------------------------
   1           D2           T2
   1           D3           T3
   1           D1           T4
   1           D3           T5
   1           D2           T6
   1           D1           T7
   2           D2           T1
   2           D1           T2
   2           D2           T3
   2           D3           T4
   2           D1           T5
   2           D4           T6

Код, который я мог бы попробовать:

SELECT caseID, D, Timestamp
FROM event e1
INNER JOIN event e2 ON e1.caseID = e2.caseID
WHERE
    CASE @D
       WHEN e1.D = D1 AND e2.D = D3 THEN ?

Ответы [ 2 ]

0 голосов
/ 08 сентября 2018

Поскольку SQL-server 2008 не поддерживает Lag и Lead, вы можете написать подзапрос, чтобы сделать его.

SELECT  caseID,
        D,
        Timestamp
FROM (
    select *,(
       select TOP 1 D
       FROM T tt 
       WHERE t1.caseID = tt.caseID 
         and t1.Timestamp < tt.Timestamp
       ORDER BY tt.Timestamp 
    ) nextD,(
       select TOP 1 D
       FROM T tt 
       WHERE t1.caseID = tt.caseID 
         and t1.Timestamp > tt.Timestamp
       ORDER BY tt.Timestamp desc
    ) pervD
    from T t1
) t1
WHERE (CASE WHEN d = 'D1' and nextD in ('D3','D4') OR
                  d = 'D2' and nextD in ('D1','D3') OR
                  d = 'D3' and nextD in ('D2','D1') OR
                  d = 'D1' and pervD in ('D2', 'D3') OR
                  d = 'D2' and pervD in ('D3')      OR
                  d = 'D3' and pervD in ('D2','D1') OR
                  d = 'D4' and pervD in ('D1') 
             THEN D END)  IS NOT NULL

sqlfiddle

0 голосов
/ 08 сентября 2018

Вот один вариант использования lead и lag с case:

select caseid, d, timestamp
from (
    select *, lead(d) over (partition by caseId order by timestamp) lead, 
              lag(d) over (partition by caseId order by timestamp) lag
    from event
    ) t
where 1 = case 
            when d = 'D1' and lead in ('D3','D4') then 1
            when d = 'D2' and lead in ('D1','D3') then 1
            when d = 'D3' and lead in ('D2','D1') then 1
            when d = 'D1' and lag in ('D2', 'D3') then 1
            when d = 'D2' and lag in ('D3') then 1
            when d = 'D3' and lag in ('D2','D1') then 1
            when d = 'D4' and lag in ('D1') then 1
            else 0
         end 
order by caseid, timestamp

Он может быть консолидирован, но хотел быть максимально четким, чтобы определить ваши критерии.

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