Лучший способ SQL Server вычислить datediff между текущей строкой и следующей строкой?

StackOverflow https://stackoverflow.com/questions/52430

  •  09-06-2019
  •  | 
  •  

Вопрос

У меня есть следующая приблизительная структура:

Object -> Object Revisions -> Data

Данные могут совместно использоваться несколькими объектами.

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

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

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

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

Это было полезно?

Решение

Если столбец identity является последовательным, вы можете использовать этот подход:

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

Другие советы

Вот пример 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)

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

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

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

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 ObjectID=@OID AND 
                       ActiveDate < ORH.ActiveDate), ActiveDate) 
FROM ObjectRevisionHistory ORH 
WHERE ObjectID=@OID


-- 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 ObjectID=@OID 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, гм...и добавляю ActiveDate во временную таблицу.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top