添加列以确保复合键是唯一的
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
列的实际情况和涉及的行数
我有一个 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
列的实际情况和涉及的行数