如何检查行的连续性?

How to check rows for continuity?

我有一个操作,如果它失败了 - 它会重试 5 次然后放弃。导致以下日志 table:

LogId   OpId  Message
1       4     Retry 1...Failed
2       4     Retry 2...Failed
3       4     Retry 3...Failed
4       4     Retry 4...Failed
5       4     Retry 5...Failed
6       4     Max Retries exceeded - giving up

有时,重试后它会成功,这意味着我永远不会在该 OpId 中看到 Max Retries exceeded - giving up 条目。

这就是我要识别的内容。被迫进入重试的操作(例如,有一个 Retry X... 条目),但没有 Max Retries exceeded - giving up 条目,因为重试在某个时候成功了。

我尝试使用 Window 函数,我认为这可能是可行的方法,但我不确定如何真正确定我想要什么。

P.S。每个 @GMB

添加自动递增字段

对于这个数据集,您也许可以只使用聚合:

select opId
from mytable
group by opId
having 
    max(case when message like 'Retry%' then 1 end) = 1
    and max(case when message = 'Max Retries exceeded - giving up' then 1 end) is null

这为您提供了 opId 的列表,其中至少有一条消息以 'Retry' 开头并且没有等于 'Max Retries exceeded - giving up'.

的消息

进入重试的任何内容都会有一个 "Retry 1...Failed" 条目,因此(假设每个集合的 opid 不同)自连接可能会起作用。

SELECT opId
   , CASE WHEN tGU.opId IS NULL THEN 'Eventually Succeeded' ELSE 'Gave Up' END AS final
FROM theTable AS t1
LEFT JOIN theTable AS tGU 
   ON t1.opId = tGU.opId 
   AND tGU.Message = "Max Retries exceeded - giving up"
WHERE t1.Message = "Retry 1...Failed"

如果你只想要最终成功的操作,你可以省略 CASE WHEN 的东西(我真的只是作为一个例子),而只是和 AND tGU.opId IS NULL 到 WHERE 子句。

但是,我认为没有真正解决这个问题的方法,当前正在重试的操作将被考虑 "eventually successful"。 (由于数据的性质,您无法真正知道 "eventually succeeded";只能知道 "didn't or hasn't yet given up"。)

另外,也许是写法的问题,但是如果"Retry 1"成功了呢? (或者 "Retry 1...Failed" 真的意味着 "Attempt 1 failed, retrying" 之类的意思吗?)

https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=307881806d4da72e5f37c080e419e00b

给定一个看起来像

的table
CREATE TABLE dbo.so_60047052(OpId int, Message varchar(50));

insert into dbo.so_60047052
SELECT * 
FROM
(
VALUES
    (4,'Retry 1...Failed')
,   (4,'Retry 2...Failed')
,   (4,'Retry 3...Failed')
,   (4,'Retry 4...Failed')
,   (4,'Retry 5...Failed')
,   (4,'Max Retries exceeded - giving up')
-- Some failure but not all
,   (5,'Retry 1...Failed')
,   (6,'Retry 1...Failed')
,   (6,'Retry 2...Failed')

,   (8,'Retry 1...Failed')
,   (8,'Retry 2...Failed')
,   (8,'Retry 3...Failed')
,   (8,'Retry 4...Failed')
)D(OpId, Message);

你可以用几种不同的方式攻击它

-- Show me anything that got into a terminal status
SELECT 
    D.OpId
,   D.Message
FROm
    dbo.so_60047052 AS D
WHERE
    D.Message = 'Max Retries exceeded - giving up';

-- Show me the "last" failing message where it didn't hit max retries
-- Last is in quotes as it's only last because the text sorts that way    
SELECT 
    D.OpId
,   D.Message
FROM
    dbo.so_60047052 AS D
WHERE
    NOT EXISTS 
    (
    SELECT * 
    FROM dbo.so_60047052 AS DI 
    WHERE DI.Message = 'Max Retries exceeded - giving up'
    AND DI.OpId = D.OpId
    )
    AND D.Message = 
    (
    SELECT MAX(DI.Message)
    FROM dbo.so_60047052 AS DI 
    WHERE 
     DI.OpId = D.OpId
    );

如果你有一个 table 记录了所有的 OpId,除了那些有问题的,你可以构建一个集 "had no issues", "had transient issues", "failed" 基于