将重复的 varchar 更新为在 SQL 数据库中唯一

发布于 2024-07-18 07:01:29 字数 137 浏览 5 评论 0原文

我需要更改数据库以在表列上添加唯一约束,但其中的 VARCHAR 数据不是唯一的。

如何通过在现有数据末尾添加序列号来更新这些重复记录,以便每个值都是唯一的?

例如,我想将“名称”更改为“名称1”、“名称2”、“名称3”

I need to change a database to add a unique constraint on a table column, but the VARCHAR data in it is not unique.

How can I update those duplicate records so that each value is unique by adding a sequential number at the end of the existing data?

e.g. I would like to change 'name' to 'name1', 'name2', 'name3'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

您的好友蓝忘机已上羡 2024-07-25 07:01:29

以下是使用 MS SQL SERVER 风格的 sql 的 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')

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

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

我回滚了每个更新,因为我的脚本文件包含这两个示例。 这使我能够在不重置表上的行的情况下测试功能。

Here are 2 examples with using the MS SQL SERVER flavor of sql.

Setup Example:

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

Sql 2005\2008: ( Computed Table Expression )

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

Sql 2000: (Cursor example)

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

I rolled back each of the updates because my script file contains both examples. This allowed me to test the functionality without resetting the rows on the table.

想你的星星会说话 2024-07-25 07:01:29

在表上打开一个游标,按该列排序。 保留一个初始化为 null 的前一个值变量和一个初始化为 0 的索引变量。如果当前值 = 前一个值,则递增索引并将索引附加到字段值。 如果当前值<> 之前的值,将索引重置为 0 并保持字段值不变。 设置前一个值变量=当前值。 移至下一行并重复。

Open a cursor on the table, ordered by that column. Keep a previous value variable, initialized to null, and an index variable initialized to 0. If the current value = the previous value, increment the index and append the index to the field value. if the current value <> the previous value, reset the index to 0 and keep the field value as is. Set the previous value variable = the current value. Move on to the next row and repeat.

濫情▎り 2024-07-25 07:01:29

您可以向其中添加另一列...例如

update mytable set mycolumn = concat(mycolumn, id) 
            where id in (<select duplicate records>);

将 id 替换为使 mycolumn 独一无二的任何列

You could add another column to it... like

update mytable set mycolumn = concat(mycolumn, id) 
            where id in (<select duplicate records>);

replace id with whatever column makes mycolumn unique

静谧幽蓝 2024-07-25 07:01:29

你使用什么数据库?

Oracle 中,有一个:

NOVALIDATE 验证更改,但不验证先前存在的数据表中

示例:

ALTER TABLE <table_name> ENABLE NOVALIDATE UNIQUE;

如果您不使用 Oracle,则检查相应数据库的 SQL 参考。

What database are you using?

In Oracle there is a:

NOVALIDATE Validates changes but does not validate data previously existing in the table

Example:

ALTER TABLE <table_name> ENABLE NOVALIDATE UNIQUE;

If you are not using Oracle then check the SQL reference for your respective database.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文