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做较少的读取。但这确实有效,当我的代表足够高时,我会投票给他。