简体   繁体   English

SQL Server查找连续失败记录

[英]SQL Server find consecutive failure records

I've look at so many other questions and nothing quite fits my question or gets me the answer I need, maybe I'm just slow today :( 我看了很多其他问题,但没有一个完全适合我的问题,也无法为我提供所需的答案,也许我今天很慢:(

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

I need to find for which InstructionDetailId's there are consecutive failures (Status = 4) by using the [Sequence] field for checking the order to determine if they are consecutive. 我需要使用[Sequence]字段检查顺序以确定它们是否连续,以查找哪些InstructionDetailId连续失败(状态= 4)。 So for the above InstructionDetailId 113 and 114 would be consecutive failures as their [Sequence] is 3 & 4, same for InstructionDetailId 118 and 119 would be consecutive failures. 因此,对于上面的InstructionDetailId 113和114,它们将是连续失败,因为它们的[Sequence]为3和4,对于InstructionDetailId 118和119,它们将是连续失败。 I've tried so many row number variation and cte's and I can't quite crack it :( This is for SQL Server 2008 R2 by the way. 我已经尝试了很多行号变化和cte,但我还不太明白:(顺便说一下,这是针对SQL Server 2008 R2的。

Expected output: 预期产量:

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

Thanx all! 谢谢大家!

Perhaps the simplest method is to use lag() and lead() : 也许最简单的方法是使用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;

You can use APPLY : 您可以使用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);

Could you do something like... 你能做点什么...

    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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM