寻找关于如何编写此代码的建议。
我有一个从一个系统移植到另一个系统的唯一值表。而且我想记录一下记录结束时的最后5个日期。
例如,项目A在2017年10月1日从System X刷新到System Y,我想将此日期存储在表格中。然后在接下来的一个月里,它又被带了4次,所以我希望这些日期值也写入该表。
既然已经编写了最后5个日期,我需要一些维护代码的方法,以便任何新的日期都会覆盖表数据,这样我们最多只能拥有最近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和更新日期写入表中,并进行某种清理程序,每个属性只保留5个条目。
如果我含糊不清,请道歉。
答案 0 :(得分:0)
如果您想保留最近的5条记录,那么它似乎是MERGE
,允许同时进行INSERT
和DELETE
活动。
此脚本演示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如何找到应保留的“其他”行以及两个not matched
子句如何处理INSERT
和DELETE
活动。
答案 1 :(得分:0)
更好地使用表格:
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而不是查看后使用,以清除数据。