2012-03-11 25 views
1

IDの自動インクリメント、文字列、および2つの整数の4つのフィールドを持つテーブルがあります。 は私が一種の何かやりたい:データベースから重複を削除するにはどうすればよいですか?

 select count(*) from table group by string 

をしてから、持っているすべての行を取るされ

1より大きいが1より大きいカウントされているすべてのカウントを統合した結果を使用し、 (同じ文字列を持つ)データベース内のこれらの行をすべて1行に置き換えると、IDは関係ありません.2つの整数は、1より大きいすべての行のすべての行の合計です。

それはいくつかの簡単なクエリを使用して可能ですか?

ありがとうございました。

答えて

0

他のユーザーがテーブルを更新しないようにすることができれば、かなり簡単です。

-- We're going to add records before deleting old ones, so keep track of which records are old. 
DECLARE @OldMaxID INT 
SELECT @OldMaxID = MAX(ID) FROM table 

-- Combine duplicate records into new records 
INSERT table (string, int1, int2) 
SELECT string, SUM(int1), SUM(int2) 
FROM table 
GROUP BY string 
HAVING COUNT(*) > 1 

-- Delete records that were used to make combined records. 
DELETE FROM table 
WHERE ID <= @OldMaxID 
GROUP BY string 
HAVING COUNT(*) > 1 
0

これを行う簡単な方法があります。

select * from (
    select count(*), string_col, sum(int_col_1), sum(int_col_2) 
    from my_table 
    group by string_col 
) as foo where count > 1 

後:ちょうどあなたが望む金額をcount > 0とのものだけを選択し、選択することでのみ複製

0

開始]を選択しますあなたの場所文で

id NOT IN (select id from table group by string) 

のようなものを置きますそのデータをテンポラリテーブルに入れ、必要のない行を削除し、テンポラリテーブルのデータを元のテーブルに挿入します。

2

私は一時テーブルのデータを文字列でグループ化し、重複がある場所にmin(id)を付けて挿入することをお勧めします。 id = min(id)の和で元の表を更新し、一致する文字列は削除しますがidは削除しません。

insert into temp 
select string, min(id) id, sum(int1) int1, sum(int2) int2 
    from table 
    group by string 
having count(*) > 1 

update table, temp 
    set table.int1 = temp.int1, 
     table.int2 = temp.int2 
where table.id = temp.id 
-- Works because there is only one record given a string in temp 
delete table 
    where exists (select null from temp where temp.string = table.string and temp.id <> table.id) 

バックアップは必須です:-)とトランザクションも必須です。

0

これは、すべて2つのクエリで実行でき、一時テーブルはありません。しかし、一度に1つの複製だけを削除するので、DELETEクエリを繰り返し実行する必要があります。行のコピーが3つある場合は、2回実行する必要があります。しかし、それ以上の結果がなくなるまで実行することができます。

カウント/合計を保持するために保持する重複行を更新します。

UPDATE tablename JOIN (
    SELECT min(id) id,sum(int1) int1,sum(int2) int2 
    FROM tablename GROUP BY string HAVING c>1 
) AS dups ON tablename.id=dups.id 
SET tablename.int1=dups.int1, tablename.int2 

次に、複数のテーブル構文を使用して、同じSELECTクエリをDELETEクエリで使用できます。

DELETE tablename FROM tablename 
JOIN (SELECT max(id) AS id,count(*) c FROM tablename GROUP BY string HAVING c>1) dups 
ON tablename.id=dups.id 

返される行がない(0の影響を受けた行)まで、DELETEを実行してください。

+0

これは、残りの行の整数がグループのすべての行(削除前)のすべての整数の合計を持つように更新されるという要件を満たしていません。 –

+0

それを指摘してくれたことに感謝します。最初に和を保存するUPDATEクエリを追加するように編集しました。 –

0

あなたはVIEWにこの情報を引き出すことができます。

CREATE VIEW SummarizedData (StringCol, IntCol1, IntCol2, OriginalRowCount) AS 
    SELECT StringCol, SUM(IntCol1), SUM(IntCol2), COUNT(*) 
    FROM TableName 
    GROUP BY StringCol 

これは、必要な情報を持つ仮想テーブルを作成します。これには、StringCol値のインスタンスが1つしかない行も含まれます。本当に必要ない場合は、フレーズHAVING COUNT(*) > 1をクエリの末尾に追加します。

あなたが元のテーブルを維持し、ちょうど集計データから読み取るか、データを「本物の」テーブルを得るためにあなたの新しいテーブルに SummarizedDataから適切な列と INSERTと空のテーブル構造を作成することができ、この方法では

関連する問題