2012-12-26 15 views
42

これにいくつかのバリエーションがありますが、達成しようとしているものと全く同じものはありません。一時テーブルを持たないMySQLテーブルの重複レコードをすべて削除するには

私は設定可能なアンケートにユーザーから与えられた回答を含むテーブルTableAを持っています。列はmember_id、quiz_num、question_num、answer_numです。

何人かのメンバーが回答を2回提出しました。だから私は、重複したレコードを削除する必要がありますが、1つの行が残っていることを確認します。 「プライマリ」列がないので、まったく同じデータを持つ2つまたは3つの行がある可能性があります。

すべての重複を削除するクエリはありますか?

+0

重複が削除された後に単純なドロップテーブルステートメントで削除できる一時的なテーブルを作成しない理由はありますか?一意のレコードのみを持つ一時テーブルを作成したり、元のテーブルからレコードを削除したり、一意のデータをロードしたり、一時テーブルを削除したりするSQLを提供できます。それが大規模なデータベースではない場合、これはあまり長くかかりません。このプロセスに関する良い記事は次のとおりです。http://www.databasejournal.com/features/mysql/article.php/10897_2201621_2/Deleting-Duplicate-Rows-in-a-MySQL-Database.htm – Kyle

+0

[How to mysqlデータベースの重複レコードを削除しますか?](http://stackoverflow.com/questions/659906/how-to-delete-duplicate-records-in-mysql-database) –

+0

私は簡単に解決策を探しています最も広い意味合い)を即座に繰り返すことができます。余分なテーブル、tempまたはnotを使用することは、これが検出されるといつでもサイトを停止させることを意味します。最高の解決策は、それが最初に起こることはないことを確認することですが、それまでは、このチェック/修正を定期的に実行してレポートが不安定な結果を出さないようにします。 – MivaScott

答えて

98

あなたのテーブルの上にUNIQUEインデックス追加:

ALTER IGNORE TABLE `TableA` 
ADD UNIQUE INDEX (`member_id`, `quiz_num`, `question_num`, `answer_num`); 

にだろうこれを行うための別の方法を:

、あなたは簡単に次のクエリを使用して、テーブルから重複を削除することができ、あなたのテーブルの主キーを追加します。

+0

私は先に進んで答えとして選択します。最終的に私は一時テーブルを使って家を清掃する必要がありますが、将来この問題がないようにUNIQUE INDEXを追加します。今私は物事が最初にどのように重複しているのか把握する必要があります。 – MivaScott

+0

華麗なもの!!!!どうもありがとう! :) – Karma

+0

@ KarmicDiceあなたが大歓迎です... –

12

これはTEMPテーブルを使用せず、実際のテーブルを代わりに使用します。問題は、テーブルの作成またはドロップテーブルについての一時テーブルではなくについてだけであれば、これは動作します:

SELECT DISTINCT * INTO TableA_Verify FROM TableA; 

DROP TABLE TableA; 

RENAME TABLE TableA_Verify TO TableA; 
13

drop table TableAの代わりに、すべてのレジスタ(delete from TableA;)を削除して元のテーブルにTableA_Verify(insert into TAbleA select * from TAbleA_Verify)からのレジスタを取り込むことができます。この方法では、元のテーブルへのすべての参照を失っていないでしょう(インデックス、...)

CREATE TABLE TableA_Verify AS SELECT DISTINCT * FROM TableA;

DELETE FROM TableA;

INSERT INTO TableA SELECT * FROM TAbleA_Verify;

DROP TABLE TableA_Verify;

6

おかげで答えをjveirasvします上記。

あなたは、列の特定のセットの重複を削除する必要がある場合

CREATE TABLE TableA_Verify AS SELECT * FROM TableA WHERE 1 GROUP BY [COLUMN TO remove duplicates BY];

DELETE FROM TableA;

INSERT INTO TableA SELECT * FROM TAbleA_Verify;(あなたがたとえば異なるテーブルにタイムスタンプを持っている場合)、あなたはこれを使用することができます

DROP TABLE TableA_Verify;

6

ユニを追加あなたのテーブルの上にqueのランキング:あなたは1回のストロークで次のクエリを実行し、任意の主キーを使用していない場合

ALTER IGNORE TABLE TableA 
ADD UNIQUE INDEX (member_id, quiz_num, question_num, answer_num); 

は仕事に非常によく

+0

ありがとうございます、それは動作しますが、1つの警告があります:1681 'IGNORE'は廃止され、将来のリリースで削除されます。重複:1警告:1 – Lebnik

2

です。値を置換することによって:

# table_name - Your Table Name 
# column_name_of_duplicates - Name of column where duplicate entries are found 

create table table_name_temp like table_name; 
insert into table_name_temp select distinct(column_name_of_duplicates),value,type from table_name group by column_name_of_duplicates; 
delete from table_name; 
insert into table_name select * from table_name_temp; 
drop table table_name_temp 
  1. 一時テーブルを作成して異なる(非重複)を格納
  2. 、削除一時テーブル
  3. 一時テーブルから元のテーブルに
  4. 空の元のテーブルを作る
  5. インサート値を値

データベースを再生する前に必ずバックアップをとることをお勧めします。

0

コメントに記載されているように、アイテムが複数回複製される場合、Saharsh Shahの回答は複数回実行する必要があります。

ここで任意のデータを削除しない解決策だし、全体の時間元のテーブルにデータを保持し、「ライブ」テーブルを維持しながら、重複が削除されるのを許可する:

alter table tableA add column duplicate tinyint(1) not null default '0'; 

update tableA set 
duplicate=if(@member_id=member_id 
      and @quiz_num=quiz_num 
      and @question_num=question_num 
      and @answer_num=answer_num,1,0), 
member_id=(@member_id:=member_id), 
quiz_num=(@quiz_num:=quiz_num), 
question_num=(@question_num:=question_num), 
answer_num=(@answer_num:=answer_num) 
order by member_id, quiz_num, question_num, answer_num; 

delete from tableA where duplicate=1; 

alter table tableA drop column duplicate; 

この基本的には、現在の行が最後の行と同じかどうかを確認し、一致する場合は重複としてマークします(orderステートメントは、重複が互いの隣に表示されることを保証します)。次に、重複レコードを削除します。最後にduplicate列を削除して元の状態に戻します。それはalter table ignoreのように見える

もすぐに離れて行くかもしれない:http://dev.mysql.com/worklog/task/?id=7395

0

別の方法は、同じ構造を持つ新しい一時テーブルを作成することです。

CREATE TABLE temp_table AS SELECT * FROM original_table LIMIT 0 

次に、表に主キーを作成します。

ALTER TABLE temp_table ADD PRIMARY KEY (primary-key-field) 

最後に、重複レコードを無視して元のテーブルからすべてのレコードをコピーします。

INSERT IGNORE INTO temp_table AS SELECT * FROM original_table 

これで、元のテーブルを削除して、新しいテーブルの名前を変更できます。

DROP TABLE original_table 
RENAME TABLE temp_table TO original_table 
関連する問題