SQL Server находит последовательные записи об ошибках - PullRequest
0 голосов
/ 12 сентября 2018

Я посмотрел на очень много других вопросов, и ничто не вполне соответствует моему вопросу или не дает мне ответ, который мне нужен, может быть, я просто медленный сегодня: (

DECLARE @t TABLE (
    [InstructionId] INT,
    [InstructionDetailId] INT,
    [Sequence] INT,
    [Status] INT
 ) 
 INSERT INTO @t SELECT 222,111,1, 2
 INSERT INTO @t SELECT 222,112,2,2
 INSERT INTO @t SELECT 222,113,3,4
 INSERT INTO @t SELECT 222,114,4,4
 INSERT INTO @t SELECT 222,115,5,2
 INSERT INTO @t SELECT 222,116,6,4
 INSERT INTO @t SELECT 222,117,7,2
 INSERT INTO @t SELECT 222,118,8,4
 INSERT INTO @t SELECT 222,119,9,4
 INSERT INTO @t SELECT 222,120,10,2
 INSERT INTO @t SELECT 222,121,11,2

Мне нужно найти, для каких InstructionDetailId есть последовательные сбои (Status = 4), используя поле [Sequence] для проверки порядка, чтобы определить, являются ли они последовательными. Таким образом, для вышеупомянутых InstructionDetailId 113 и 114 будут последовательными сбоями, поскольку их [Sequence] равен 3 и 4, то же самое для InstructionDetailId 118 и 119 будет последовательными сбоями. Я пробовал так много вариаций номеров строк и cte's, и я не могу его взломать :( Кстати, это для SQL Server 2008 R2.

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

InstructionId   InstructionDetailId Sequence    Status
222                            113       3           4
222                            114       4           4
222                            118       8           4
222                            119       9           4

Спасибо всем!

Ответы [ 3 ]

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

Вы можете использовать APPLY:

select t.*
from @t t outer apply
     ( select top (1) t1.*
       from @t t1
       where t1.InstructionId = t.InstructionId and
             t1.Sequence < t.Sequence
       order by t1.Sequence desc
     ) t1 outer apply
     ( select top (1) t2.*
       from @t t2
       where t2.InstructionId = t.InstructionId and
             t2.Sequence > t.Sequence
       order by t2.Sequence 
     ) t2
where t.status = 4 and (t.status = t1.status or t.status = t2.status);
0 голосов
/ 12 сентября 2018

Не могли бы вы сделать что-то вроде ...

    select t1.InstructionID,
           t1.InstructionDetailID,
           t1.Sequence,
           t1.Status,
      from @t t1
     inner join @t t2 on t1.InstructionID = t2.InstructionID
                     and t1.Sequence = (t2.Sequence - 1)
                     and t1.Status = t2.Status
                     and t1.Status = 4
0 голосов
/ 12 сентября 2018

Возможно, самый простой способ - это использовать lag() и lead():

select t.*
from (select t.*,
             lag(t.status) over (partition by t.InstructionId order by t.sequence) as prev_status,
             lead(t.status) over (partition by t.InstructionId order by t.sequence) as next_status
      from @t t
     ) t
where status = prev_status or status = next_status;
...