SQL 服务器:存储最后 5 个日期

SQL Server : storing last 5 dates

正在寻求有关如何编写此代码的建议。

我有 table 个唯一值正在从一个系统移植到另一个系统。我想存储一个记录,比如记录被带过来的最后 5 个日期。

例如,项目 A 在 2017 年 10 月 1 日从系统 X 刷新到系统 Y,我想将此日期存储在 table 中。然后在接下来的一个月里,它又被带来了 4 次,所以我希望这些日期值也写入 table。

现在已经写入了最后 5 个日期,我需要一些方法来维护代码,以便任何新出现的日期都将覆盖 table 数据,这样我们将始终最多拥有table.

最近 5 次更新日期

示例数据; 日期列表示每个 属性 行发生的最后 5 次更新。

Property ID's, Date 1,   Date 2,   Date 3,  Date 4,   Date 5
1              01/07/17, 01/08/17 01/10/17 05/10/17 10/10/17
2              01/01/17 01/03/17 01/06/17 05/10/17 10/10/17
3              01/02/17 05/02/17 01/10/17 05/10/17 10/10/17
4              01/03/17 01/08/17 01/10/17

如果 属性 4 有来自系统 X 的更新,则填充日期 4。 如果 属性 3 有来自系统 x 的更新,日期 2 到 5 将向左移动一个位置,日期 5 将填充最新日期。

这是记录最近 5 次更新的最佳方式吗?

或者,我可以将每个 属性 id 和更新日期写入 table 并进行某种清理程序,每个 属性.[= 仅保留 5 个条目。 12=]

抱歉,如果我含糊不清。

如果您想保留最近的 5 条记录,那么似乎 MERGE,同时允许 INSERTDELETE activity 可能是可行的方法。

此脚本演示了一个 MERGE 保留每个 ID 值的最近 5 行:

create table #History (ID int not null, OccurredAt datetime2(7) not null)
go
declare @current table (ID int not null)
insert into @current (ID) values (1),(3)

;With Keeps as (
    select
        *,ROW_NUMBER() OVER (PARTITION BY ID ORDER BY OccurredAt desc) as rn
    from #History
    where ID in (select ID from @current)
)
merge into #History t
using (select ID,SYSDATETIME() from @current
        union all
      select ID,OccurredAt from Keeps where rn between 1 and 4) s(ID,OccurredAt)
on
    t.ID = s.ID and
    t.OccurredAt = s.OccurredAt
when not matched then insert (ID,OccurredAt) values (s.ID,s.OccurredAt)
when not matched by source and t.ID in (select ID from @current) then delete;

waitfor delay '00:00:01'
go 30
select * from #History

希望您能看到 CTE 如何找到应该保留的 "other" 行,以及两个 not matched 子句如何处理 INSERTDELETE 活动。

更好地使用 table 如:

CREATE TABLE dbo.ChangeDates (
    PropertyID int,
    DateChanged date
)

并且只在其中写入数据。然后像这样创建视图:

CREATE VIEW dbo.Top5ChangeDates 
AS
WITH cte AS (
    SELECT  PropertyID,
            DateChanged,
            ROW_NUMBER() OVER (PARTITION BY PropertyID ORDER BY DateChanged DESC) as rn
    FROM dbo.ChangeDates
)

SELECT  PropertyID,
        DateChanged
FROM cte
WHERE rn <= 5
GO

或在插入 TRIGGER 而不是视图后使用,以清除数据。