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 作为主键
有人能解决以下问题吗? (两种情况下的代码片段都应 运行 作为完整块)
以下代码模拟了日常处理作业的情况。
这是第 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 作为主键