单一选择查询中的表未更新

问题描述

我有一个需要更新的临时表,第一行已更新,但第二行已更新为null,请帮忙

declare @T Table
(
 ID int,Name nvarchar(20),rownum int 
)

insert into @T(ID,rownum)
select ID,rownum = ROW_NUMBER() OVER(order by id) from testtabel4

select * from testtabel4

update @t
set Name=case when rownum>1 then (select top 1 Name from @T x where x.rownum=(y.rownum-1))
 else 'first' end
from @t y

select * from @T 

这里是testtabel4的定义

CREATE TABLE [dbo].[testtabel4](
    [ID] [int] IDENTITY(1,1) NOT NULL,[Name] [nvarchar](80) NULL,PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF,STATISTICS_norECOmpuTE = OFF,IGnorE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

这是输出

ID  Name
1   first
2   NULL

解决方法

您仅在@T中插入两列:

insert into @T (ID,rownum)
    select ID,ROW_NUMBER() OVER (order by id) 
    from testtabel4;

您没有插入name,因此在所有行上都是NULL。因此,then表达式的case部分将始终为NULL

,

我认为最好使用lag()和可更新的CTE来编写您的更新。

with cte as (
    select name,lag(name,1,'first') over(order by rownum) lag_name
    from @t
)
update cte set name = lag_name

使用此技术,可以清楚地看到实际上并不需要先馈入表格,然后将其插入表中。您可以一次完成两项操作,就像这样:

insert into @t (id,name,rownum)
select 
    id,'first') over(order by id),row_number() over(order by id) 
from testtabel4

我不确定您是否甚至不再需要rownum列,除非出于其他目的需要它。