2011-11-02 120 views
3
在表

我有数据在以下格式SQL查询来更新行

ID DocNumber RevOrder 
1 DOC-001  NULL 
2 DOC-001  NULL 
3 DOC-001  NULL 
4 DOC-002  NULL 
5 D0C-002  NULL 
6 D0C-003  NULL 

我需要在更新RevOrder列格式如下

ID DocNumber RevOrder 
1 DOC-001  3 
2 DOC-001  2 
3 DOC-001  1 
4 DOC-002  2 
5 D0C-002  1 
6 D0C-003  1 

逻辑是:DocNumber可被复制和带有最大ID的DocNumber获得RevOrder = 1,然后获取RevOrder = 2等等......我如何实现上述场景?

+0

你不期待'DOC_001'的下一个实例重新编号的一切都是你?也就是说,让'id = 1'将RevOrder更改为4? –

回答

3

使用基于一个ROW_NUMBER()在分区此UPDATE声明:

;WITH UpdateData AS 
(
    SELECT 
     ID, DocNumber, 
     ROW_NUMBER() OVER(PARTITION BY DocNumber ORDER BY ID DESC) AS 'RowNum' 
    FROM dbo.YourTable 
) 
UPDATE dbo.YourTable 
SET RevOrder = RowNum 
FROM dbo.YourTable t 
INNER JOIN UpdateData ud ON t.ID = ud.ID 
0

从SQL Server 2005及以上版本,你可以使用

RANK() OVER (PARTITION BY DocNumber ORDER BY ID ASC) AS RevOrder 
+0

@marc_s不,它按DocNumber进行分区(因此排序会根据请求在DocNumber的每次更改时重新开始)。它的行为非常像您提出的ROW_NUMBER()解决方案,除了RANK()会给具有相同DocNumber和相同ID的行赋予相同的编号。由于ID是唯一的,我认为RANK()的行为与此ROW_NUMBER()完全相同。然而,在更一般的情况下,使用ROW_NUMBER()的解决方案更为正确。 –

0

我想具有分区by子句的row_number()函数将工作

declare @temp as table(
ID int not null 
,Doc_Num varchar(20) not null 
,RevOrder int null 
) 
insert into @temp 
values 
(1,'DOC-001',null) 
,(2,'DOC-001',null) 
,(3,'DOC-001',null) 
,(4,'DOC-002',null) 
,(5,'DOC-002',null) 
,(6,'DOC-003',null) 


select * from @temp 


select 
t.ID 
,t.Doc_Num 
,ROW_NUMBER() over(partition by t.Doc_num order by t.ID desc) 
from 
@temp t 
order by t.ID