Sql server 用以前的记录值更新最新记录

Sql server 用以前的记录值更新最新记录,sql-server,tsql,stored-procedures,sql-update,window-functions,Sql Server,Tsql,Stored Procedures,Sql Update,Window Functions,我有一个名为Audits的表,它有一个CompanyId、Date、AuditNumber字段,每个公司都可以有许多审计,AuditNumber字段跟踪公司有多少审计 我正在尝试将所有最新的审计记录日期更新为之前的日期+5年,因此假设公司ID 12345有3次审计,我想将第三次审计更新为最新的一次审计记录日期,第二次审计记录日期+5年,以此类推。。。基本上对所有最新的记录都这样做 到目前为止,我一直在尝试使用while循环来实现这一点,但我非常困惑,因为它并没有完全实现我想要的功能 DECLAR

我有一个名为Audits的表,它有一个CompanyId、Date、AuditNumber字段,每个公司都可以有许多审计,AuditNumber字段跟踪公司有多少审计

我正在尝试将所有最新的审计记录日期更新为之前的日期+5年,因此假设公司ID 12345有3次审计,我想将第三次审计更新为最新的一次审计记录日期,第二次审计记录日期+5年,以此类推。。。基本上对所有最新的记录都这样做

到目前为止,我一直在尝试使用while循环来实现这一点,但我非常困惑,因为它并没有完全实现我想要的功能

DECLARE @counter INT = 1;
WHILE(@counter <= (SELECT COUNT(*) FROM Audits WHERE AuditNumber > 1)
BEGIN
    UPDATE Audits
    SET Date = CASE
                   WHEN AuditNumber > 1 THEN (SELECT TOP 1 DATEADD(YEAR, 5, Date) FROM Audits WHERE AuditNumber < (SELECT(MAX(AuditNumber) FROM Audits))
                   END
    WHERE AuditNumber > 1
    SET @counter = @counter + 1
END
我不是SQL方面的专家,但由于选择TOP1,这只是用它可以找到的上一个日期更新日期,但是如果我不放置TOP1,子查询将返回多个记录,因此它会抱怨

任何帮助都将不胜感激


谢谢

不需要过程和循环。我建议使用窗口函数和可更新的cte:

with cte as (
    select date, 
        row_number() over(partition by company order by auditnumber desc) rn,
        lag(date) over(partition by company order by auditnumber) lag_date
    from audits
)
update cte 
set date = dateadd(year, 5, lag_date) 
where rn = 1 and lag_date is not null
公共表表达式按审核编号降序排列具有相同公司的记录,并检索上一次审核的日期。外部查询过滤每个组的顶部记录,并将日期更新为前一日期后5年


当一家公司只有一次审计时,您没有告诉该怎么做。我添加了一个不更新这些行(如果有)的条件。

您必须先将行号添加到结果中,然后将结果与self-ON连接起来 Al.CompanyId=A2.CompanyId和Al.IND=1和A2.IND=2,现在您在一条记录中有了最新记录和以前的记录,并且可以更新原始表

WITH A AS
(
    SELECT *,ROW_NUMBER(PARTITION BY CompanyId ORDER BY AuditNumber DESC) IND FROM Audits
),B AS 
(
    SELECT Al.CompanyId,A1.AuditNumber,A2.[DATE] FROM A A1 INNER JOIN A A2 ON Al.CompanyId=A2.CompanyId AND Al.IND=1 AND A2.IND=2
)UPDATE _Audits SET _Audits.[Date]= DATEADD(YEAR,5,B.[DATE]) FROM
B LEFT JOIN Audits _Audits ON B.CompanyId=_Audits.CompanyId AND B.AuditNumber=_Audits.AuditNumber

谢谢,这帮了大忙。