为唯一名称sql server提供唯一的ID

时间:2018-08-15 10:08:55

标签: sql sql-server database

我有一个包含名称的sql server表:

Serial  Name
1      Roger
2      John
3      John
4      Mike
5      Roger
6      John
7      Mike

我想插入一个UID列,该列将具有唯一名称的唯一ID。因此,它看起来应该像

Serial  Name    UID
1      Roger     1
2      John      2
3      John      2
4      Mike      3
5      Roger     1
6      John      2
7      Mike      3

任何人都可以帮助我进行查询。

3 个答案:

答案 0 :(得分:1)

要即时选择它,请使用以下方法:

with CTE as
(
select name, dense_rank() over (order by name) as rn
from MyTable
)
select t1.id, t1.name, t2.rn
from MyTable t1
inner join CTE t2
on t2.name = t1.name

要进行烘焙,请创建一个带有identity(1,0)列的新名称表,并将新名称添加到此列表中(一起获取灵感)

create table name_uid
(
id      int identity(1,0) not null,
name    varchar(50)
)

insert into name_uid (name)
select distinct name 
from mytable

alter table mytable
add the_uid int

alter table
add constraint fk_name_uid foreign key (the_uid) references name_uid(id)

update t1
set t1.the_uid = t2.id
from Mytable t1
inner join name_uid t2
on t1.name = t2.name

create trigger tr_uid on MyTable
for insert
as
declare @name varchar
declare @exist int
declare @uid  int
begin
select @name = i.name from inserted i;
select @exist = case when exists (select 1 from name_uid where name = @name) then 1 else 0 end;
begin
if @exist = 0
insert into name_uid (name) values (@name);
end;
select @uid = select id from name_uid where name = @name;
update MyTable;
set the_uid = @uid;
go

答案 1 :(得分:1)

首先将列添加到表中。

ALTER TABLE yourtable
ADD [UID] INT NULL;

ALTER TABLE yourtable
ADD constraint fk_yourtable_uid_id foreign key ([UID]) references yourtable([Serial]);

然后,您可以使用每个名称的最小Serial ID更新UID。

UPDATE t
SET [UID] = q.[UID]
FROM yourtable t
JOIN
(
  SELECT Name, MIN([Serial]) AS [UID]
  FROM yourtable
  GROUP BY Name
) q ON q.Name = t.Name
WHERE (t.[UID] IS NULL OR t.[UID] != q.[UID]) -- Repeatability

答案 2 :(得分:1)

只需使用dense_rank()

select t.*, dense_rank() over (order by name) as unique_id
from t;

如果您想保留第一列的原始顺序,则可以使用:

select t.*, min(serial) over (partition by name) as unique_id
from t;

这会有差距。您可以将它们结合起来以获得独特的无间隙序列:

select t.*, dense_rank() over (order by seqnum) as unique_id
from (select t.*, min(serial) over (partition by name) as seqnum
      from t
     ) t;

此方法的优点是稳定-假设第一列是一个身份列(因此,随着时间的推移添加的新名称将比现有名称具有更高的serial值)。