添加列以确保复合键是唯一的

Add column to ensure composite key is unique

我有一个 table,它需要一个基于 2 列的复合主键 (Material number, Plant)。

例如,这是目前的情况(注意这些行不是唯一的):

MATERIAL_NUMBER    PLANT NUMBER
------------------ ----- ------
000000000000500672 G072  1
000000000000500672 G072  1
000000000000500672 G087  1
000000000000500672 G207  1
000000000000500672 G207  1

但是,我需要将附加列 (NUMBER) 添加到复合键中,以便每一行都是唯一的,并且它必须像这样工作:

对于每个 MATERIAL_NUMBER,对于每个 PLANT,让 NUMBER 从 1 开始,并为每个重复记录递增 1。

这将是所需的输出:

MATERIAL_NUMBER    PLANT NUMBER
------------------ ----- ------
000000000000500672 G072  1
000000000000500672 G072  2
000000000000500672 G087  1
000000000000500672 G207  1
000000000000500672 G207  2

我将如何实现这一目标,特别是在 SQL 服务器中?

此致!

已解决。

见下文:

SELECT MATERIAL_NUMBER, PLANT, (ROW_NUMBER() OVER (PARTITION BY MATERIAL_NUMBER, PLANT ORDER BY VALID_FROM)) as NUMBER
FROM Table_Name

将输出有问题的 table,正确定义 NUMBER 列

假设这是真实的 table,

create table #temp1(MATERIAL_NUMBER varchar(30),PLANT varchar(30), NUMBER int)

假设你只想插入一条记录,

declare @Num int
select @Num=isnull(max(number),0) from #temp1 where MATERIAL_NUMBER='000000000000500672' and PLANT='G072'

insert into #temp1 (MATERIAL_NUMBER,PLANT , NUMBER )
values ('000000000000500672','G072',@Num+1)

假设你想插入批量record.Your批量记录样本数据就像

create table #temp11(MATERIAL_NUMBER varchar(30),PLANT varchar(30))
insert into #temp11 (MATERIAL_NUMBER,PLANT)values
 ('000000000000500672','G072')
,('000000000000500672','G072')
,('000000000000500672','G087')
,('000000000000500672','G207')
,('000000000000500672','G207')

You want to insert `#temp11` in `#temp1` maintaining number id

insert into #temp1 (MATERIAL_NUMBER,PLANT , NUMBER )
select t11.MATERIAL_NUMBER,t11.PLANT 
,ROW_NUMBER()over(partition by t11.MATERIAL_NUMBER,t11.PLANT order by (select null))+isnull(maxnum,0) as Number from #temp11 t11
outer apply(select MATERIAL_NUMBER,PLANT,max(NUMBER)maxnum from #temp1 t  where t.MATERIAL_NUMBER=t11.MATERIAL_NUMBER  
and t.PLANT=t11.PLANT group by MATERIAL_NUMBER,PLANT) t

select * from #temp1
drop table #temp1
drop table #temp11

主要问题是为什么需要数字列?在大多数情况下你不需要数字列,你可以使用 ROW_NUMBER()over(partition by t11.MATERIAL_NUMBER,t11.PLANT order by (select null)) 来显示你需要的地方。这样会更有效率。

或者说出你需要Number列的实际情况和涉及的行数