我有以下粗略结构:
Object -> Object Revisions -> Data
可以在多个对象之间共享数据。
我要做的是清理旧的对象修订版。我想保留第一个,活动的和一系列修订,以便保留一段时间的最后一次更改。数据可能会在2天内发生很大变化,然后单独使用数月,因此我希望在更改开始之前保留最后一次修订并更新新集。
我目前正在使用游标和临时表来保存更改之间的ID和日期,以便我可以选择低挂水果来摆脱。这意味着使用@LastID,@ LastDate,更新和插入临时表等...
在不使用游标和临时表的情况下,是否有更简单/更好的方法来计算初始结果集中当前行和下一行之间的日期差异?
我在sql server 2000上,但对2005年,2008年的任何新功能感兴趣,也可能对此有所帮助。
答案 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做了更少的读取。但是它确实有效,当我让我的代表足够高时,我会投票给他。