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

时间:2020-03-05 18:50:12  来源:igfitidea点击:

我有以下大致结构:

Object -> Object Revisions -> Data

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

我想做的是清除旧的"对象修订"。我想保留第一个,活跃的修订版本,以便保留一段时间内的最后一个更改。数据可能会在2天的过程中发生很大变化,然后搁置几个月,所以我想在更改开始和新设置的结束更改之前保留最新的修订。

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

有没有一种更简便/更好的方法来计算初始结果集中当前行和下一行之间的日期差,而无需使用游标和临时表?

我使用的是sql server 2000,但对2005、2008的任何新功能也可能会有所帮助。

解决方案

回答

这是示例SQL。如果我们有"身份"列,则可以使用它代替" 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即可。

回答

嗯,有趣的挑战。我认为,如果我们使用2005年新增的数据透视功能,则可以在没有自连接的情况下完成此操作。

回答

这是我到目前为止所取得的成果,我想花一点时间在接受答案之前。

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

我希望扩展此范围,以便我最多可以保留这么多修订,并从旧版本中删掉一些旧版本,同时仍保留第一个,最后一个和活动版本。通过选择top和order by子句,um ...并将ActiveDate放入临时表中,应该足够容易。

我得到了Peter的示例,但是接受了该示例并将其修改为子选择。我搞砸了两者和sql跟踪显示subselect做较少的读取。但这确实有效,当我的代表足够高时,我会投票给他。