因此,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
因此,上面的方法非常有用,可以找到结果,在这些结果中,只有两次连续的失败
结果:
现在从上述结果中发现的唯一记录是连续发生 2 次失败的记录,但是每当我将以上内容转换为实际的测试环境表时,它似乎都无法正常工作。
测试环境结果:正如您看到的2518380的“ InstructionId”一样,它带回了一条记录,而对于“ InstructionId” 2614351来说,这意味着带回了2条记录的集合。
测试环境查询:(几乎完全相同)
;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(*)的变化,但是还没有成功。非常感谢
答案 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。