2013-05-08 2 views
1
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 (не работает)Уникальная база ID на другой колонке

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

select * from #ABC 

Итак, я таблица #abc уже заселена ID и NAME, я хочу, чтобы заполнить «Имя2 ', так что' name2 'не должен иметь то же значение, что и' name 'для того же ID. Например, для ID = 1 все значения name2 должны отличаться от значений имен. Thanks

+0

Пожалуйста, ** всегда ** укажите конкретную ** систему баз данных ** (и какую версию), которую вы используете. SQL - это просто язык запросов - используется многими базами данных ..... –

+0

SQL SERVER 2012 –

ответ

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)) 

Это будет работать до 99 дублей для данного идентификатора.

К сожалению, у меня нет SQL Server, доступного прямо сейчас. Но вот идея. Вы можете взять максимальное значение имени, а затем выполнить арифметику, базу 36 (26 альфа и 10 цифр). В результате получается примерно следующее:

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' в этом случае).

+0

Если вы заметили, имя и имя2 является varchar (2), мне нужно использовать SUBSTRING (REPLACE (CONVERT (VARCHAR (36), NEWID()), '-', ''), 0, 3) , чтобы система случайно получала двухзначные значения. и ваш запрос не работает :( –

+0

Спасибо, что отредактировал ваш ответ, но он по-прежнему не работает должным образом. Я хочу двухзначные числа в имени2, и они не должны дублироваться с именем для того же ID –

+0

@BhupinderSingh .... очень сложно гарантировать уникальность, если у вас нет чего-то вроде символа, который не используется в 'name' или списке всех возможных значений name2. –

Смежные вопросы