SQL Server计算当前行和下一行之间的datediff的最佳方法?

时间:2008-09-09 17:33:29

标签: sql-server datediff

我有以下粗略结构:

Object -> Object Revisions -> Data

可以在多个对象之间共享数据。

我要做的是清理旧的对象修订版。我想保留第一个,活动的和一系列修订,以便保留一段时间的最后一次更改。数据可能会在2天内发生很大变化,然后单独使用数月,因此我希望在更改开始之前保留最后一次修订并更新新集。

我目前正在使用游标和临时表来保存更改之间的ID和日期,以便我可以选择低挂水果来摆脱。这意味着使用@LastID,@ LastDate,更新和插入临时表等...

在不使用游标和临时表的情况下,是否有更简单/更好的方法来计算初始结果集中当前行和下一行之间的日期差异?

我在sql server 2000上,但对2005年,2008年的任何新功能感兴趣,也可能对此有所帮助。

4 个答案:

答案 0 :(得分: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”,但请假设您需要从中删除ID。

答案 1 :(得分:1)

如果标识列是顺序的,您可以使用此方法:

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

答案 2 :(得分:0)

嗯,有趣的挑战。如果您使用new-to-2005 pivot功能,我认为如果没有自联接,您可以这样做。

答案 3 :(得分: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 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跟踪显示了subselect做了更少的读取。但是它确实有效,当我让我的代表足够高时,我会投票给他。