SQL Server Сравнение последующих строк для дубликатов - PullRequest
2 голосов
/ 07 декабря 2009

Я пытаюсь написать запрос SQL Server, но мне не повезло, и мне было интересно, есть ли у кого-нибудь идеи о том, как выполнить мой запрос.

Что я пытаюсь сделать:

У меня есть таблица с несколькими столбцами, в которой указаны столбцы с именами TaskID, StatusCode, Timestamp. Теперь эта таблица содержит только задачи для одной из наших систем, которые работают в течение дня, и когда что-то запускается, она получает метку времени и код состояния в зависимости от состояния для этой задачи.

Иногда происходит то, что таблица задач будет обновлена ​​с новой отметкой времени, но код состояния не изменится с момента последнего обновления задачи, поэтому для двух или более последовательных строк данной задачи код состояния может быть одинаковым. Когда я говорю последовательные строки, я имею в виду временную метку.

Таким образом, пример задачи 88 может иметь двадцать строк в statusCode 2, после чего код состояния меняется на что-то другое.

Теперь то, что я сейчас пытаюсь сделать без удачи, - это извлечь из этой таблицы список всех задач, кодов состояния и временных меток, но в случае, когда у меня есть несколько последовательных строк для задачи с тот же код состояния, я просто хочу взять первую строку с самой низкой отметкой времени и игнорировать оставшуюся часть строки, пока код состояния для этой задачи не изменится.

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

У кого-нибудь есть идеи относительно того, как я могу это сделать, или, может быть, что-то, что я мог бы прочитать, чтобы помочь мне?

Спасибо Ирфан.

Ответы [ 3 ]

2 голосов
/ 07 декабря 2009

Это пара способов получить то, что вы хотите:

SELECT
     T1.task_id,
     T1.status_code,
     T1.status_timestamp
FROM
     My_Table T1
LEFT OUTER JOIN My_Table T2 ON
     T2.task_id = T1.task_id AND
     T2.status_timestamp < T1.status_timestamp
LEFT OUTER JOIN My_Table T3 ON
     T3.task_id = T1.task_id AND
     T3.status_timestamp < T1.status_timestamp AND
     T3.status_timestamp > T2.status_timestamp
WHERE
     T3.task_id IS NULL AND
     (T2.status_code IS NULL OR T2.status_code <> T1.status_code)
ORDER BY
     T1.status_timestamp

или

SELECT
     T1.task_id,
     T1.status_code,
     T1.status_timestamp
FROM
     My_Table T1
LEFT OUTER JOIN My_Table T2 ON
     T2.task_id = T1.task_id AND
     T2.status_timestamp = (
          SELECT
               MAX(status_timestamp)
          FROM
               My_Table T3
          WHERE
               T3.task_id = T1.task_id AND
               T3.status_timestamp < T1.status_timestamp)
WHERE
     (T2.status_code IS NULL OR T2.status_code <> T1.status_code)
ORDER BY
     T1.status_timestamp

Оба метода основаны на том, что нет точных совпадений значений status_timestamp (две строки не могут иметь одинаковое точное значение status_timestamp для данного task_id.)

1 голос
/ 07 декабря 2009

Что-то вроде

select TaskID,StatusCode,Min(TimeStamp)
from table
group by TaskID,StatusCode
order by 1,2

Обратите внимание, что код состояния может дублироваться, вам потребуется дополнительное поле, но, надеюсь, это может указать вам правильное направление ...

0 голосов
/ 07 декабря 2009

Что-то вроде следующего должно привести вас в правильном направлении ....

CREATE TABLE #T
(
    TaskId INT
    ,StatusCode INT
    ,StatusTimeStamp DATETIME
)

INSERT INTO #T
SELECT 1, 1, '2009-12-01 14:20'
UNION SELECT 1, 2, '2009-12-01 16:20'
UNION SELECT 1, 2, '2009-12-02 09:15'
UNION SELECT 1, 2, '2009-12-02 12:15'
UNION SELECT 1, 3, '2009-12-02 18:15'

;WITH CTE AS
(
SELECT TaskId
        ,StatusCode
        ,StatusTimeStamp
        ,ROW_NUMBER() OVER (PARTITION BY TaskId, StatusCode ORDER BY TaskId, StatusTimeStamp DESC)  AS RNUM
FROM  #T
)
SELECT TaskId
        ,StatusCode
        ,StatusTimeStamp
FROM CTE
WHERE RNUM = 1

DROP TABLE #T
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...