SQL:选择具有条件的两个连续行

SQL:选择具有条件的两个连续行,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有一个包含3列的表事件,希望选择两个具有相同案例id的连续行,并使用以下特定条件规则。根据给定的标准,我有大约5k+个不同的案例id可供选择,下面只是2个案例id的示例。我有部分代码要尝试,但由于我不知道如何在满足条件的情况下同时选择这两行,所以我被卡住了 规则: 如果D1后跟D3,则选择两行 如果ELSE D1后面跟着D4,则选择两行 如果D2后面跟着D1,则选择两行 如果D2后面跟着D3,则选择两行 如果D3后面跟着D2,则选择两行 如果D3后面跟着D1,则选择两行 否则不要选择 表事件:

我有一个包含3列的表事件,希望选择两个具有相同案例id的连续行,并使用以下特定条件规则。根据给定的标准,我有大约5k+个不同的案例id可供选择,下面只是2个案例id的示例。我有部分代码要尝试,但由于我不知道如何在满足条件的情况下同时选择这两行,所以我被卡住了

规则:

如果D1后跟D3,则选择两行 如果ELSE D1后面跟着D4,则选择两行 如果D2后面跟着D1,则选择两行 如果D2后面跟着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 ?
这里有一个选项,在案例中使用超前和滞后:

它可以合并,但希望尽可能明确地定义您的条件。

由于SQL server 2008不支持滞后和超前,您可以编写一个子查询来实现

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