其他列的唯一ID

时间:2013-05-08 00:19:25

标签: sql sql-server-2012

DROP TABLE #ABC
CREATE TABLE #ABC (ID INT NOT NULL, Name VARCHAR (2) NOT NULL, name2 VARCHAR(2))
INSERT INTO #ABC (ID, NAME)
VALUES (1,'01'),(1,'F5'),(1,'05'),(1,'08'),(1,'02'), (1,'03'), (1,'04'), (1,'06'),(1,'07'),(1,'09'),(1,'10'),(1,'11'),(1,'12'),(1,'13'),(1,'14'),
(1,'15'),(1,'2D'),(1,'2E'),(1,'4B'),(1,'5F'),(1,'64'),(1,'73'),(1,'83'),(1,'88'),(1,'A9'),(1,'AC'),(1,'D0'),(1,'D7'),(1,'15'),(2,'76'),(2,'J5')

脚本我用来填充name2(不工作)

UPDATE A
SET name2 = SUBSTRING(REPLACE(CONVERT(VARCHAR(36), NEWID()) , '-', ''), 0, 3)
FROM #ABC AS A

select * from #ABC

因此,我已经使用ID和NAME填充了表#ABC,我想填充'Name2',以便'name2'与同一ID的'name'不应该具有相同的值。例如,对于ID = 1,所有name2值应与名称值不同。 谢谢

1 个答案:

答案 0 :(得分:0)

看起来您正在使用SQL Server。如果是这样,您可以使用row_number()函数将唯一标识符附加到name的末尾:

with toupdate as (
      select t.*, row_number() over (partition by id order by name desc) as num
      from #abc t
     )
update toupdate
    set name2 = cast(num as varchar(2))

对于给定的ID,这最多可以使用99个重复项。

不幸的是,我现在没有可用的SQL Server。但这是一个想法。您可以获取name的最大值,然后执行算术,base 36(26 alpha和10 numeric)。结果是这样的:

with toupdate as (
      select t.*, row_number() over (partition by id order by name desc) as seqnum,
             max(name) over (partition by id) as maxname,
             ((case when left(name, 1) between '0' and '9'
                    then ascii(left(name, 1))
                    else ascii(upper(left(name, 1))) - ascii('A')+10
               end) * 36 +
              (case when right(name, 1) between '0' and '9'
                    then ascii(right(name, 1))
                    else ascii(upper(right(name, 1))) - ascii('A')+10
               end)
             ) as namenum
      from #abc t
     )
update toupdate
    set name2 = (case when (namenum+seqnum)/36 < 10
                      then char(ascii('0')+((namenum+seqnum)/36))
                      else char(ascii('A')+((namenum+seqnum)/36) - 10)
                 end)+
                (case when ((namenum+seqnum)%36) < 10
                      then char(ascii('0')+((namenum+seqnum)%36))
                      else char(ascii('A')+((namenum+seqnum)%36) - 10)
                 end)

找到最大名称,然后生成大于该名称的名称。这假设您仅使用字母字符(大写)和数字。如果name接近最大可能值(在这种情况下为'ZZ'),则可能会失败。