SQL 服务器:列的自动增量,按另一列中的值分区

SQL Server : autoincrement for column, partitioned by values in another column

有人能解决以下问题吗? (两种情况下的代码片段都应 运行 作为完整块)

以下代码模拟了日常处理作业的情况。

这是第 1 天

Declare @poitem_source table (PONum int, txt varchar(50), status varchar(25)) 
Declare @poitem_destination table (PONum int, LineNum int, txt varchar(50)) 

insert @poitem_source 
values (1,'Item1', 'NEW'), (1,'Item2', 'NEW'), 
       (1,'Item3', 'NEW'), (2,'Item1', 'NEW'), 
       (2,'Item2', 'NEW')

update @poitem_source 
set status = 'PROCESSING' 
where status = 'NEW'

insert @poitem_destination 
   SELECT 
      PONum, 
      ROW_NUMBER() OVER (PARTITION BY PONum ORDER BY PONum) AS POLineNumber, 
      txt 
   FROM 
      @poitem_source 
   WHERE 
      status = 'PROCESSING'

update @poitem_source 
set status = 'DONE' 
where status = 'PROCESSING'

select * 
from @poitem_destination 
order by PONum, txt

如果你 运行 它,你会看到 LineNum 为目标 table 中的每个 PONum 增加 1...n。

但是,这显然不适用于第 2 天...这是代码...

Declare @poitem_source table (PONum int, txt varchar(50), status varchar(25)) 
Declare @poitem_destination table (PONum int, LineNum int, txt varchar(50)) 

insert @poitem_source 
values (1,'Item1', 'NEW'), (1,'Item2', 'NEW'), (1,'Item3', 'NEW'), 
       (2,'Item1', 'NEW'), (2,'Item2', 'NEW')

update @poitem_source 
set status = 'PROCESSING' 
where status = 'NEW'

insert @poitem_destination 
   select
      PONum, 
      ROW_NUMBER() OVER (PARTITION BY PONum ORDER BY PONum) AS POLineNumber, 
      txt 
   from 
      @poitem_source 
   where 
      status = 'PROCESSING'

update @poitem_source 
set status = 'DONE' 
where status = 'PROCESSING'

select * 
from @poitem_destination 
order by PONum, txt

--- 2nd day

insert @poitem_source 
values (1,'Item4', 'NEW'), (2,'Item3', 'NEW')

update @poitem_source 
set status = 'PROCESSING' 
where status = 'NEW'

insert @poitem_destination 
   select
      PONum, 
      ROW_NUMBER() OVER (PARTITION BY PONum ORDER BY PONum) AS POLineNumber, 
      txt 
   from @poitem_source 
   where status = 'PROCESSING'

update @poitem_source 
set status = 'DONE' 
where status = 'PROCESSING'

select * 
from @poitem_destination 
order by PONum, txt

对于第 2 天,其他项目的行号为 1,因为 select 查询没有以任何方式链接到目标 table(而且我不相信它可以).

有人有生成这些行号的替代解决方案吗?

谢谢

向您的 table 添加一个 IDENTITY 列(这将是 table 主键的一个很好的候选者)。这将在 table 中为其提供一个唯一的递增行号。然后您可以维护您的每日行号。

像这样:

Declare @poitem_source table (ID int IDENTITY(1,1) NOT NULL PRIMARY KEY, PONum int, txt varchar(50), status varchar(25))

或者,您可以将行号列设置为 IDENTITY(1,1);但是,这会丢失数据,并可能导致您以后遇到问题("I need LineNumber X from day Y ..." 现在更难获得)。

解决方法如下

Declare @poitem_source table (PONum int, txt varchar(50), status varchar(25)) 
Declare @poitem_destination table (PONum int, LineNum int, txt varchar(50)) 


insert @poitem_source values (1,'Item1', 'NEW'), (1,'Item2', 'NEW'), (1,'Item3', 'NEW'), (2,'Item1', 'NEW'), (2,'Item2', 'NEW')

update @poitem_source set status = 'PROCESSING' where status = 'NEW'

insert @poitem_destination 
SELECT PONum, ROW_NUMBER()  OVER(PARTITION BY PONum ORDER BY PONum) + (select isnull(max(linenum),0) from @poitem_destination d where d.PONum = s.PONum)  AS POLineNumber, txt from @poitem_source s where status = 'PROCESSING'

select * from @poitem_destination order by PONum, txt

update @poitem_source set status = 'DONE' where status = 'PROCESSING'

--- 2nd day

insert @poitem_source values (1,'Item4', 'NEW'), (2,'Item3', 'NEW')

update @poitem_source set status = 'PROCESSING' where status = 'NEW'

insert @poitem_destination 
SELECT PONum, ROW_NUMBER()  OVER(PARTITION BY PONum ORDER BY PONum) + (select isnull(max(linenum),0) from @poitem_destination d where d.PONum = s.PONum)  AS POLineNumber, txt from @poitem_source s where status = 'PROCESSING'

update @poitem_source set status = 'DONE' where status = 'PROCESSING'

select * from @poitem_destination order by PONum, txt

所以现在我们可以使用 PONum 和 LineNum 作为主键