【问题标题】:SQL Server find consecutive failure recordsSQL Server 查找连续失败记录
【发布时间】:2019-02-16 22:39:04
【问题描述】:

我已经看了很多其他问题,但没有什么能完全符合我的问题或得到我需要的答案,也许我今天很慢:(

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

我需要通过使用 [Sequence] 字段来检查顺序以确定它们是否是连续的,从而找出哪些 InstructionDetailId 存在连续失败(状态 = 4)。因此,对于上述 InstructionDetailId 113 和 114 将是连续失败,因为它们的 [Sequence] 是 3 和 4,对于 InstructionDetailId 118 和 119 将是连续失败。我已经尝试了很多行号变化和 cte,但我无法完全破解它:( 顺便说一下,这是针对 SQL Server 2008 R2 的。

预期输出:

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

谢谢大家!

【问题讨论】:

  • 发布预期输出
  • 当你看到这些问题时,你自己有没有尝试过?您用来尝试获得所需结果的代码是什么,为什么它们不正确?
  • @Larnu 是的,正如我上面提到的,我已经尝试了很多差异 cte 和行号变化,但并没有完全理解
  • @jjay225 然后发布该代码,以便我们查看您出错的地方,并帮助您纠正它。
  • 上面的结果集可以只用一个WHERE子句就可以得到吗?

标签: sql sql-server tsql sql-server-2008 common-table-expression


【解决方案1】:

也许最简单的方法是使用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;

【讨论】:

  • Thanx Gordon 但我忘了补充说我需要它用于 SQL Server 2008,刚刚编辑了我的问题。
【解决方案2】:

你可以使用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);

【讨论】:

    【解决方案3】:

    你能做点什么吗...

        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
    

    【讨论】:

      猜你喜欢
      • 2017-04-12
      • 1970-01-01
      • 2016-01-02
      • 2022-01-01
      • 2021-02-20
      • 2017-05-20
      • 2023-03-17
      • 1970-01-01
      • 2018-12-01
      相关资源
      最近更新 更多