我需要根据accountId表中的以 1 开头的序列号更新一列。我该怎么做呢?
所以OrderID是NULL开始。所以对于每一行AccountID我需要更新OrderID从 1 开始并按顺序更新,所以我的数据是这样出来的。该表被称为Renewals
RowID AccountID OrderID
1 A 1
2 A 2
4 A 3
5 B 1
6 B 2
7 C 1
Run Code Online (Sandbox Code Playgroud)
使用公用表表达式with row_number()to partition byAccountId和 order by [RowId]:
;with cte as (
select *
, NewOrderId = row_number() over (
partition by AccountId
order by [RowId]
)
from Renewals
)
update cte
set OrderId = NewOrderId;
Run Code Online (Sandbox Code Playgroud)
不使用公用表表达式:
update r
set OrderId = NewOrderId
from (
select *
, NewOrderId = row_number() over (
partition by AccountId
order by [RowId]
)
from Renewals
) as r
Run Code Online (Sandbox Code Playgroud)
测试设置:http : //rextester.com/FSUD49402
create table Renewals (
[RowId] int not null
, AccountId char(1) not null
, OrderId int null
);
insert into Renewals (RowId, AccountId) values
(1,'A'), (2,'A'), (4,'A')
, (5,'B'), (6,'B'), (7,'C');
with cte as (
select
[RowId]
, AccountId
, OrderId
, NewOrderId = row_number() over (
partition by AccountId
order by [RowId]
)
from Renewals
)
update cte
set OrderId = NewOrderId;
select * from Renewals;
Run Code Online (Sandbox Code Playgroud)
结果是:
+-------+-----------+---------+
| RowId | AccountId | OrderId |
+-------+-----------+---------+
| 1 | A | 1 |
| 2 | A | 2 |
| 4 | A | 3 |
| 5 | B | 1 |
| 6 | B | 2 |
| 7 | C | 1 |
+-------+-----------+---------+
Run Code Online (Sandbox Code Playgroud)
要回答此答案的评论中的问题:
我正在使用此数据来更新上一行。[...] 我试图表明上面的第 1 行被第 2 行更新被第 4 行替换,第 4 行尚未更新
可以通过以下方式完成:
select
r.*
, RenewedBy=p.RowId
from Renewals as r
left join Renewals as p
on p.AccountId = r.AccountId
and p.OrderId = r.OrderId+1
Run Code Online (Sandbox Code Playgroud)
返回:
+-------+-----------+---------+-----------+
| RowId | AccountId | OrderId | RenewedBy |
+-------+-----------+---------+-----------+
| 1 | A | 1 | 2 |
| 2 | A | 2 | 4 |
| 4 | A | 3 | NULL |
| 5 | B | 1 | 6 |
| 6 | B | 2 | NULL |
| 7 | C | 1 | NULL |
+-------+-----------+---------+-----------+
Run Code Online (Sandbox Code Playgroud)
如果这是前一个的唯一原因update,我们根本不必到update桌子上。这将得到与上面相同的结果:
;with cte as (
select *
, rn = row_number() over (
partition by AccountId
order by [RowId]
)
from Renewals
)
select
r.RowId
, r.AccountId
, OrderId = r.rn
, RenewedBy=p.RowId
from cte as r
left join cte as p
on p.AccountId = r.AccountId
and p.rn = r.rn+1
Run Code Online (Sandbox Code Playgroud)
这对你有用吗?
set nocount on
Declare @Renewals table (RowId int, AccountId varchar(10), OrderId int)
insert into @Renewals (RowId, AccountId, OrderId) values (1,'A',null)
insert into @Renewals (RowId, AccountId, OrderId) values (2,'A',null)
insert into @Renewals (RowId, AccountId, OrderId) values (4,'A',null)
insert into @Renewals (RowId, AccountId, OrderId) values (5,'B',null)
insert into @Renewals (RowId, AccountId, OrderId) values (6,'B',null)
insert into @Renewals (RowId, AccountId, OrderId) values (7,'C',null)
UPDATE a
SET OrderId = (
SELECT count(*) + 1
FROM @Renewals
WHERE AccountId = a.AccountId
AND RowId < a.RowId
)
FROM @Renewals a
SELECT *
FROM @Renewals
Run Code Online (Sandbox Code Playgroud)