2008-09-09 11 views
0

я получил следующую примерную структуру:SQL Server лучший способ расчета датирования между текущей строкой и следующей строкой?

Object -> Object Revisions -> Data 

данные могут быть разделены между несколькими объектами.

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

В настоящее время я использую таблицу курсора и темпа, чтобы удерживать идентификаторы и дату между изменениями, чтобы я мог выбрать из них низко висящие фрукты, чтобы избавиться. Это означает использование @LastID, @LastDate, обновление и вставки в временную таблицу и т. Д.

Есть ли простой/лучший способ рассчитать разницу дат между текущей строкой и следующей строкой в ​​моем первоначальном наборе результатов без использования курсора и таблицы temp?

Я на сервере sql 2000, но буду интересоваться любыми новыми функциями 2005, 2008, которые также могут помочь в этом.

ответ

1

Если столбец идентификаторов последователен вы можете использовать этот подход:

SELECT curr.*, DATEDIFF(MINUTE, prev.EventDateTime,curr.EventDateTime) Duration FROM DWLog curr join DWLog prev on prev.EventID = curr.EventID - 1

+0

Это хороший чистый раствор. Я чувствую себя глупо, не думая об ID-1. – ddowns 2014-01-29 17:06:25

4

Вот пример SQL. Если у вас есть столбец Identity, вы можете использовать его вместо «ActivityDate».

SELECT DATEDIFF(HOUR, prev.ActivityDate, curr.ActivityDate) 
    FROM MyTable curr 
    JOIN MyTable prev 
    ON prev.ObjectID = curr.ObjectID 
    WHERE prev.ActivityDate = 
    (SELECT MAX(maxtbl.ActivityDate) 
     FROM MyTable maxtbl 
     WHERE maxtbl.ObjectID = curr.ObjectID 
      AND maxtbl.ActivityDate < curr.ActivityDate) 

Я мог бы удалить "prev", но имейте это в виду, что вам нужны идентификаторы из него для удаления.

0

Hrmm, интересные задачи. Я думаю, вы можете сделать это без самообучения, если вы используете функциональность pivot от new-to-2005.

0

Вот что у меня есть, я хотел дать это немного больше времени, прежде чем принимать ответ.

DECLARE @IDs TABLE 
(
    ID int , 
    DateBetween int 
) 

DECLARE @OID int 
SET @OID = 6150 

-- Grab the revisions, calc the datediff, and insert into temp table var. 

INSERT @IDs 
SELECT ID, 
     DATEDIFF(dd, 
       (SELECT MAX(ActiveDate) 
       FROM ObjectRevisionHistory 
       WHERE [email protected] AND 
         ActiveDate < ORH.ActiveDate), ActiveDate) 
FROM ObjectRevisionHistory ORH 
WHERE [email protected] 


-- Hard set DateBetween for special case revisions to always keep 

UPDATE @IDs SET DateBetween = 1000 WHERE ID=(SELECT MIN(ID) FROM @IDs) 

UPDATE @IDs SET DateBetween = 1000 WHERE ID=(SELECT MAX(ID) FROM @IDs) 

UPDATE @IDs SET DateBetween = 1000 
WHERE ID=(SELECT ID 
      FROM ObjectRevisionHistory 
      WHERE [email protected] AND Active=1) 


-- Select out IDs for however I need them 

SELECT * FROM @IDs 
SELECT * FROM @IDs WHERE DateBetween < 2 
SELECT * FROM @IDs WHERE DateBetween > 2 

Я ищу, чтобы расширить это так, что я могу держать на максимальных так много изменений, и подрезать от старших из них в то же время сохраняя первый, последний и активный. Должно быть достаточно легко с помощью select top и order by clauses, um ... и бросания в ActiveDate в таблицу temp.

Я получил пример Питера, но взял его и внес в него подзаголовок. Я столкнулся с обоими, а трассировка sql показывает, что подзаголовок делает меньше чтений. Но он работает, и я проголосую за него, когда я получу свою репутацию достаточно высоко.