テーブルの列に一意制約を追加するためにデータベースを変更する必要がありますが、その中のVARCHARデータは一意ではありません。重複するvarcharsをSQLデータベース内でユニークに更新する
これらの重複レコードを更新して、既存のデータの末尾に連番を追加して各値を一意にするにはどうすればよいですか?
「名前」を「名前1」、「名前2」、「名前3」に変更したい
テーブルの列に一意制約を追加するためにデータベースを変更する必要がありますが、その中のVARCHARデータは一意ではありません。重複するvarcharsをSQLデータベース内でユニークに更新する
これらの重複レコードを更新して、既存のデータの末尾に連番を追加して各値を一意にするにはどうすればよいですか?
「名前」を「名前1」、「名前2」、「名前3」に変更したい
どのデータベースをお使いですか? Oracleで
があります:
NOVALIDATEは、変更内容を検証しますが、テーブル内の既存の以前のデータを検証しません
例:
ALTER TABLE <table_name> ENABLE NOVALIDATE UNIQUE;
はあなたがSQLを確認するOracleを使用していない場合それぞれのデータベースの参照。
あなたはそれに別の列を追加することができます...のような
update mytable set mycolumn = concat(mycolumn, id)
where id in (<select duplicate records>);
MYCOLUMNユニーク
開き、その列によって注文テーブルの上にカーソルを、作るものは何でもコラムでIDを交換してください。以前の値変数をnullに初期化し、インデックス変数を0に初期化します。現在の値が前の値の場合は、インデックスを増分してインデックスをフィールド値に追加します。現在の値<>前の値の場合は、インデックスを0にリセットし、フィールド値をそのままにします。以前の値の変数=現在の値を設定します。次の行に移動し、繰り返します。
ここには、SQLのMS SQL SERVERフレーバを使用した2つの例があります。
設定例:2008 \ 2005
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:(コンピュータテーブル式)が
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
[email protected] 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
私は背中の各圧延しました私のスクリプトファイルには両方の例が含まれているので、更新してください。これにより、テーブルの行をリセットせずに機能をテストすることができました。
私たちはFrontBase(SQL92準拠)を使用しています 私は既存のデータを検証して更新します。 –
-1、これは彼が求めているものではありません。 –
私はそれが彼が尋ねたものではないことを知っていますが、彼がFrontBaseを使っていると言っている前にそれを書きました。しかし、原則は同じです:データベースはNOVALIDATE節と同様の何かを持つことができます。 CONSTRAINTの種類が変更されたと思われる場合は、PRIMARY KEYを気にしないでください。 – Azder