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
,同时允许 INSERT
和 DELETE
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
子句如何处理 INSERT
和 DELETE
活动。
更好地使用 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 而不是视图后使用,以清除数据。
正在寻求有关如何编写此代码的建议。
我有 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
,同时允许 INSERT
和 DELETE
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
子句如何处理 INSERT
和 DELETE
活动。
更好地使用 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 而不是视图后使用,以清除数据。