如何检查行的连续性?
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" 基于
我有一个操作,如果它失败了 - 它会重试 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
给定一个看起来像
的tableCREATE 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" 基于