SQL Server 计算当前行和下一行之间的 datediff 的最佳方法?
-
09-06-2019 - |
题
我有以下粗略结构:
Object -> Object Revisions -> Data
数据可以在多个对象之间共享。
我想做的是清除旧的对象修订。我想保留第一个、活跃的、广泛的修订,以便保留一段时间内的最后一个更改。数据可能会在 2 天内发生很大变化,然后几个月内都不会发生变化,因此我想保留更改开始之前的最后修订以及新集的最终更改。
我目前正在使用游标和临时表来保存更改之间的 ID 和日期,以便我可以选择要摆脱的容易实现的目标。这意味着使用 @LastID、@LastDate、更新和插入临时表等...
有没有一种更简单/更好的方法来计算初始结果集中当前行和下一行之间的日期差异,而不使用游标和临时表?
我使用的是 sql server 2000,但对 2005、2008 的任何新功能感兴趣,这些功能也可以帮助解决这个问题。
解决方案
如果标识列是连续的,您可以使用此方法:
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)
我可以删除“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
我希望扩展它,以便我可以保留最多的修订,并删除旧的修订,同时仍然保留第一个、最后一个和活动的修订。通过 select top 和 order by 子句应该很容易,嗯......并将 ActiveDate 放入临时表中。
我让彼得的例子可以工作,但将其修改为子选择。我把两者都弄乱了,sql 跟踪显示子选择执行的读取较少。但这确实有效,当我的声望足够高时,我会投票给他。