Как проверить строки на непрерывность? - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть операция, которая в случае неудачи повторяется 5 раз, а затем сдается. В результате получается следующая таблица журнала:

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

Иногда после повторной попытки это будет выполнено успешно, что означает, что я никогда не увижу запись Max Retries exceeded - giving up в этом OpId.

И это то, что я пытаюсь идентифицировать. Операции, которые были вынуждены go к повторным попыткам (например, есть запись Retry X...), но нет записи Max Retries exceeded - giving up, потому что в какой-то момент повторная попытка была успешной.

Я пытался использовать функции окна , и я думаю, что это может быть путь к go, но я не уверен, как на самом деле определить, что я хочу.

PS Добавлено поле с автоматическим увеличением для @ GMB

Ответы [ 3 ]

1 голос
/ 04 февраля 2020

Все, что идет на повторные попытки, будет иметь запись «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.

Однако, и я не думаю, что на самом деле есть способ обойти это, повторное выполнение операции в настоящее время будет считаться "в конечном итоге успешным". (Из-за характера данных вы не можете знать, «в конце концов, все получилось»; только «не сдался» или «еще не сдался».)

Кроме того, возможно, это формулировка, но что если "Повторить 1" успешно? (Или «Retry 1 ... Failed» действительно означает что-то вроде «Попытка 1 не удалась, повторная попытка»?)

1 голос
/ 04 февраля 2020

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

Учитывая таблицу, которая выглядит примерно так:

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
    );

Если у вас есть таблица, в которой записаны все OpId, кроме тех, которые имеют проблемы, вы можете затем создать набор, который "не имел проблем", "имел временные проблемы", "не прошел" на основе

1 голос
/ 04 февраля 2020

Для этого набора данных вы можете просто использовать агрегацию:

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'.

...