SQL:如何基于上一行更新行

SQL:如何基于上一行更新行,sql,sql-server,Sql,Sql Server,我有下表: id-家庭id-家庭状态-以前的家庭状态 1 - a - occupied - null 2 - a - abandoned - null 3 - a - foreclosure - null 4 - b - occupied - null 5 - b - occupied - null 6 - c - occupied - null 我想生成一个更新语句,如下所示更新表: 1 - a - occupied - abandoned 2 - a

我有下表:

id-家庭id-家庭状态-以前的家庭状态

1  - a - occupied - null

2  - a - abandoned - null 

3  - a - foreclosure - null 

4  - b - occupied - null  

5  - b - occupied - null 

6  - c - occupied - null 
我想生成一个更新语句,如下所示更新表:

1  - a - occupied - abandoned

2  - a - abandoned - foreclosure 

3  - a - foreclosure - null 

4  - b - occupied - occupied  

5  - b - occupied - null 

6  - c - occupied - null
我使用以下算法:

set @id = 1
set @max_id = (select MAX(id) from home)

select @homeid = homeid from home where id = @id

while @id <= @max_id
begin

     select 
        @previous_homeid = home,
        @previous_home_status = @home_status
    from 
        home where id = (@id + 1)

    if(@previous_homeid = @homeid)
    begin
        update 
            home 
        set  
            home_status = @previous_home_status
        where 
            id = @id
    end

    set @homeid = @previous_homeid
    set @previous_homeid = null
    set @previous_home_status = null
    set @id = @id + 1;
end
有没有更有效的算法?我不喜欢循环效率

您可以使用lead获得下一行的值

with cte as (select t.*
             ,lead(home_status) over(partition by home_id order by id) as next_home_status
             from tbl t)
update cte set previous_home_status=next_home_status
您可以使用lead获取下一行的值

with cte as (select t.*
             ,lead(home_status) over(partition by home_id order by id) as next_home_status
             from tbl t)
update cte set previous_home_status=next_home_status

这是未经测试的,但应该可以满足您的需求:

WITH CTE AS(
    SELECT id, [home id], [home status], [previous home status],
           LEAD([previous home status]) OVER (PARTITION BY [home id] ORDER BY id ASC) AS NextStatus
    FROM home)
UPDATE CTE
SET [previous home status] = NextStatus;

这是未经测试的,但应该可以满足您的需求:

WITH CTE AS(
    SELECT id, [home id], [home status], [previous home status],
           LEAD([previous home status]) OVER (PARTITION BY [home id] ORDER BY id ASC) AS NextStatus
    FROM home)
UPDATE CTE
SET [previous home status] = NextStatus;

谢谢,两者都一样,对吗。我只接受快一点的。谢谢,两者都一样,对吗。我只接受快一点的。