T-SQL分组按2的多个批次

时间:2018-09-18 14:26:50

标签: sql-server tsql sql-server-2008 sql-server-2008-r2

因此,stackoverflow上的出色人员帮助我进行了“查找连续失败”类型查询。 (状态= 4为失败)。我以为我已经破解了问题的第二部分,因为我的测试用例似乎可以正常工作,但是每当我在测试环境中运行它时,我都会得到不可靠的结果,因此我必须做错了什么。目标是找到X个连续失败的次数。因此,以下设置可查找2个连续失败。我正在使用SQL Server 2008 R2

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
INSERT INTO @t SELECT 222,124,12,4
INSERT INTO @t SELECT 222,126,13,4
INSERT INTO @t SELECT 222,128,14,4

INSERT INTO @t SELECT 223,126,13,4
INSERT INTO @t SELECT 223,128,14,4
INSERT INTO @t SELECT 223,129,15,2
INSERT INTO @t SELECT 223,130,16,4

INSERT INTO @t SELECT 224,111,17,4
INSERT INTO @t SELECT 224,112,18,4

INSERT INTO @t SELECT 223,160,33,4
INSERT INTO @t SELECT 223,161,34,4
INSERT INTO @t SELECT 223,162,35,4
INSERT INTO @t SELECT 223,163,40,4


;with HardcoreCTE AS
(
 select t.*,
  t.[Sequence] - ROW_NUMBER() OVER(PARTITION BY t.instructionId ORDER BY 
  t.InstructionDetailId) AS ItemCount
  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)
)
,

HardCoreCTE2
 AS
 (
 select *, Count(1) OVER(PARTITION BY ItemCount) AS ItemCount2 from 
 HardcoreCTE
 )

 select * from HardCoreCTE2
 where ItemCount2 =2

因此,上面的方法非常有用,可以找到结果,在这些结果中,只有两次连续的失败

结果:

enter image description here

现在从上述结果中发现的唯一记录是连续发生 2 次失败的记录,但是每当我将以上内容转换为实际的测试环境表时,它似乎都无法正常工作。

测试环境结果:正如您看到的2518380的“ InstructionId”一样,它带回了一条记录,而对于“ InstructionId” 2614351来说,这意味着带回了2条记录的集合。

enter image description here

测试环境查询:(几乎完全相同)

;with InitialDataCTE
AS
(
   SELECT Instruction.InstructionID,InstructionDetail.InstructionDetailID, 
   InstructionDetail.InstructionDetailStatusID AS [Status],
   InstructionDetail.Sequence
   FROM     Instruction INNER JOIN
              InstructionDetail ON Instruction.InstructionID = 
   InstructionDetail.InstructionID

              where InstructionDetailStatusID =4
              and InstructionDetail.PaymentDateOriginal between '2015-01-05' 
       AND '2018-09-08'
  ),
  HardCoreCTE
  AS
  (
select t.*,
t.Sequence - ROW_NUMBER() OVER(PARTITION BY t.instructionId ORDER BY 
t.InstructionDetailId) AS ItemCount
from InitialDataCTE t outer apply
 ( select top (1) t1.*
   from InitialDataCTE t1
   where t1.InstructionId = t.InstructionID and
         t1.Sequence < t.Sequence
   order by t1.Sequence desc
 ) t1 outer apply
 ( select top (1) t2.*
   from InitialDataCTE 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)
)
,
 HardCoreCTE2
 AS
 (
 select *, Count(1) OVER(PARTITION BY ItemCount) AS ItemCount2 from 
 HardCoreCTE
 )
 select * from HardCoreCTE2
 where ItemCount2 =2
 order by InstructionID, Sequence

如果有人可以告诉我我要去哪里错,我真的很感激,我一直在搞怪Count(*)的变化,但是还没有成功。非常感谢

1 个答案:

答案 0 :(得分:1)

我来到下一个查询:

with
  a as (
    select *,
      row_number() over(partition by InstructionId order by Sequence)-
      row_number() over(partition by InstructionId, [Status] order by Sequence) g
    from @t
  ),
  b as (
    select *,
      count(*) over(partition by InstructionId, [Status], g) c
    from a
    where [Status] = 4
  )
select *
from b
where c > 2
order by 1, 3;

对于您的测试数据,我得到了以下结果:

InstructionId   InstructionDetailId Sequence    Status  g   c
222             224                 312         4       6   3
222             226                 413         4       6   3
222             228                 514         4       6   3
223             161                 84          4       2   3
223             162                 95          4       2   3
223             163                 140         4       2   3

您可以测试此查询here