3 sql database unique duplicates
我需要更改数据库以在表列上添加唯一约束,但其中的VARCHAR数据不是唯一的.
如何通过在现有数据末尾添加序号来更新这些重复记录,以使每个值都是唯一的?
例如,我想将'name'更改为'name1','name2','name3'
以下是使用sql的MS SQL SERVER风格的2个示例.
设置示例:
create table test (id int identity primary key, val varchar(20) )
--id is a pk for the cursor so it can update using "where current of"
-- name a is not duplicated
-- name b is duplicated 3 times
-- name c is duplicated 2 times
insert test values('name a')
insert test values('name b')
insert test values('name c')
insert test values('name b')
insert test values('name b')
insert test values('name c')
Run Code Online (Sandbox Code Playgroud)
Sql 2005\2008 :(计算表表达式)
begin tran; -- Computed table expressions require the statement prior to end with ;
with cte(val,row) as (
select val, row_number() over (partition by val order by val) row
--partiton is important. it resets the row_number on a new val
from test
where val in ( -- only return values that are duplicated
select val
from test
group by val
having count(val)>1
)
)
update cte set val = val + ltrim(str(row))
--ltrim(str(row)) = converting the int to a string and removing the padding from the str command.
select * from test
rollback
Run Code Online (Sandbox Code Playgroud)
Sql 2000 :(光标示例)
begin tran
declare @row int, @last varchar(20), @current varchar(20)
set @last = ''
declare dupes cursor
for
select val
from test
where val in ( -- only return values that are duplicated
select val
from test
group by val
having count(val)>1
)
order by val
for update of val
open dupes
fetch next from dupes into @current
while @@fetch_status = 0
begin
--new set of dupes, like the partition by in the 2005 example
if @last != @current
set @row = 1
update test
--@last is being set during the update statement
set val = val + ltrim(str(@row)), @last = val
where current of dupes
set @row = @row + 1
fetch next from dupes into @current
end
close dupes
deallocate dupes
select * from test
rollback
Run Code Online (Sandbox Code Playgroud)
我回滚了每个更新,因为我的脚本文件包含两个示例.这使我可以在不重置表格中的行的情况下测试功能.