2009-12-07 9 views
2

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

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

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

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

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

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

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

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

Thanks Irfan.

+0

Я забыл упомянуть что я использую SQL SERVER 2005 – Iffy

+0

то, что вы пытаетесь сделать, звучит очень процедурно для меня - так что, возможно, вам будет лучше делать это в чем-то вроде C#, а не пытаться сгибать T-SQL. –

+0

Эй, Марк, вы знаете, что я думал, но причина, по которой я пытаюсь это сделать, - уменьшить нагрузку на SQL. Без этой логики для некоторых задач я могу получить несколько тысяч строк из-за большого количества повторяющихся строк кодов состояния. Если я могу уменьшить набор результатов, чтобы содержать только разные строки на основе кода состояния, это значительно ускорит процесс. – Iffy

ответ

2

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

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

+0

Спасибо Том, я использовал второй запрос с некоторыми модами, чтобы работать для моих целей, но он сделал трюк и был очень быстрым. Большое спасибо за помощь. – Iffy

+0

добро пожаловать! –

1

Что-то вроде

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

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

+0

спасибо, что ответ Sparky.Это действительно близко, но проблема с этим заключается в таблице. Я хочу игнорировать оставшуюся строку для заданного состояния для задачи, если последующие последовательные строки имеют одинаковый код состояния. Например. Задача может перейти к коду состояния 2, а затем к 3, а затем к 2, и все это допустимые строки, которые я хочу показать, поскольку код состояния 2 не выполнялся последовательно. Я думаю, что ваш запрос даст мне временную метку min для данного статуса в этой задаче. Вот почему мой запрос настолько странный из-за проблемы последовательных строк. – Iffy

0

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

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 
+0

Спасибо, Джей, это очень умный запрос, но опять же у него такая же проблема, как и запрос выше Sparky, где он группирует код состояния и taskid вместе и возвращает только одну строку для каждого кода состояния. Например, если бы я должен был поставить строку UNION SELECT 1, 2, '2009-12-02 19:15'; в ваш запрос, где этот код состояния уже вставлен, но этот не является последовательным для остальных, поэтому должен отображаться. Какой выше запрос представляет собой группу этой строки с другими. – Iffy

+0

Я думал, может быть, писать курсор, где я отслеживаю предыдущий код состояния, и если его то же самое, что и текущий, я не вхожу в мою временную таблицу, если он отличается от того, что я делаю запись в мою временную таблицу. В конце этого я буду иметь временную таблицу с данными, которые я хочу быть с более медленным запросом из-за курсора. Все это зависит от того, сколько времени занимает курсор для выполнения этой операции для нескольких сотен строк, если я пойду так? – Iffy

Смежные вопросы