MySQLで重複する行を削除する


375

次のフィールドを持つテーブルがあります。

id (Unique)
url (Unique)
title
company
site_id

次に、同じを持つ行を削除する必要がありtitle, company and site_idます。これを行う1つの方法は、スクリプト(PHP)とともに次のSQLを使用することです。

SELECT title, site_id, location, id, count( * ) 
FROM jobs
GROUP BY site_id, company, title, location
HAVING count( * ) >1

このクエリを実行した後、サーバー側のスクリプトを使用して重複を削除できます。

しかし、これがSQLクエリを使用してのみ実行できるかどうかを知りたいです。


1
簡単な質問:重複(title、company、site_id)が常に存在しないようにしたいですか?その場合、データベースに制約を設定して、title、company、およびsite_idが一意になるようにします。つまり、クリーンアッププロセスは必要ありません。また、SQLは1行で済みます。
J. Polfer、2010

1
stackoverflowのこのリンクを参照しください。それは私にとって魅力的に機能しました。

このソリューションをお勧めします(別のスレッドで投稿):stackoverflow.com/a/4685232/195835
Simon East

回答:


607

これを行う非常に簡単な方法はUNIQUE、3つの列にインデックスを追加することです。ALTERステートメントを作成するときに、IGNOREキーワードを含めます。そのようです:

ALTER IGNORE TABLE jobs
ADD UNIQUE INDEX idx_name (site_id, title, company);

これにより、すべての重複行が削除されます。追加の利点として、INSERTs重複している将来はエラーになります。いつものように、あなたはこのようなものを実行する前にバックアップを取りたいかもしれません...


8
興味深いですが、IGNORE句がそれらの重複を削除することを前提としているため、ニーズと一致しない可能性があります。不正確な値が最も近い許容可能な一致に切り捨てられているのはいいですね
OMGポニー2010

75
念のため、InnoDBを使用しているときに問題が発生する可能性がある場合は、InnoDBデータベースでのALTER IGNORE TABLEの使用に関する既知のバグがあります。
DarkMantis


42
InnoDBテーブルの場合は最初に次のクエリを実行しますset session old_alter_table=1;
shock_one

51
これは5.7.4ではサポートされなくなりました。dev.mysql.com/ doc / refman / 5.7 / en / alter
Ray Baxter

180

列のプロパティを変更したくない場合は、以下のクエリを使用できます。

一意のID(auto_increment列など)を持つ列があるので、それを使用して重複を削除できます。

DELETE `a`
FROM
    `jobs` AS `a`,
    `jobs` AS `b`
WHERE
    -- IMPORTANT: Ensures one version remains
    -- Change "ID" to your unique column's name
    `a`.`ID` < `b`.`ID`

    -- Any duplicates you want to check for
    AND (`a`.`title` = `b`.`title` OR `a`.`title` IS NULL AND `b`.`title` IS NULL)
    AND (`a`.`company` = `b`.`company` OR `a`.`company` IS NULL AND `b`.`company` IS NULL)
    AND (`a`.`site_id` = `b`.`site_id` OR `a`.`site_id` IS NULL AND `b`.`site_id` IS NULL);

MySQLでは、NULLセーフの等号演算子(別名「宇宙船演算子」)を使用して、さらに単純化できます

DELETE `a`
FROM
    `jobs` AS `a`,
    `jobs` AS `b`
WHERE
    -- IMPORTANT: Ensures one version remains
    -- Change "ID" to your unique column's name
    `a`.`ID` < `b`.`ID`

    -- Any duplicates you want to check for
    AND `a`.`title` <=> `b`.`title`
    AND `a`.`company` <=> `b`.`company`
    AND `a`.`site_id` <=> `b`.`site_id`;

3
このソリューションは適切に機能していません。重複したレコードをいくつか作成しようとしましたが、(20行が影響を受けた)のようなものですが、もう一度実行すると、(4行が影響を受けた)と(0行が影響を受けた)まで表示されます。これはちょっと怪しいですが、ここが私にとって最も効果的なものです。ほとんど同じですが、1回の実行で機能します。ソリューションを編集しました
Nassim

1
@Nassim:私の場合(MySQLの場合)は完全に機能するため、この回答とは異なることをしている必要があります。
Lawrence Dol

3
私のように混乱した人にとっては、MySQLではNULLはNULLと等しくないため、NULL比較条件が必要です。関連する列がNULLでないことが保証されている場合は、これらの用語を省略できます。
Ian

3
はい。MYSQL5.7以降、受け入れられた回答は無効になりました。これは、普遍的であり、一時テーブルの作成も必要ないため、実際に受け入れられた回答になるはずです。
that-ben 2018

1
特定のレコード(たとえば、100から1に削減される)のコピーが多数あり、その状態のレコードが多数ある場合は、非常に遅い。代わりに、stackoverflow.com / a / 4685232/199364をお勧めします。私見、常にリンクされたアプローチを使用します。本質的に高速な手法です。
ToolmakerSteve

78

MySQLには、削除するテーブルの参照に関する制限があります。次のように、一時テーブルを使用して回避できます。

create temporary table tmpTable (id int);

insert  into tmpTable
        (id)
select  id
from    YourTable yt
where   exists
        (
        select  *
        from    YourTabe yt2
        where   yt2.title = yt.title
                and yt2.company = yt.company
                and yt2.site_id = yt.site_id
                and yt2.id > yt.id
        );

delete  
from    YourTable
where   ID in (select id from tmpTable);

コメントでのコスタノスの提案から:
非常に大きなデータベースがある場合、上記の唯一の遅いクエリはDELETEです。このクエリはより高速になる可能性があります。

DELETE FROM YourTable USING YourTable, tmpTable WHERE YourTable.id=tmpTable.id

3
@andomar、これは、where句のフィールドの1つにnullが含まれている場合を除き、正常に機能します。例:sqlfiddle.com
コーダー

1
Insert SQLは高価なものですか?MySQLデータベースでタイムアウトになるので不思議に思っています。
Cassio 2013年

4
ここで唯一遅いクエリは、大きなデータベースがある場合のDELETEクエリです。このクエリは速くなることができます:DELETE FROM YourTable USING YourTable, tmpTable WHERE YourTable.id=tmpTable.id
Kostanos

@Kostanosだけでなく、一時テーブルにDELETEINSERT時間がかかりました。したがって、tmpテーブルのインデックスはcreate index tmpTable_id_index on tmpTable (id)、少なくとも私にとっては非常に役立ちます。
Jiezhi.G

1
あなたのテーブルが大きい場合、それは野生のでインデックスを追加する価値がある: -create temporary table tmpTable (id int, PRIMARY KEY (id));
ダラス・クラーク

44

IGNOREステートメントが私の場合のように機能しない場合は、以下のステートメントを使用できます。

CREATE TABLE your_table_deduped LIKE your_table;


INSERT your_table_deduped
SELECT *
FROM your_table
GROUP BY index1_id,
         index2_id;

RENAME TABLE your_table TO your_table_with_dupes;

RENAME TABLE your_table_deduped TO your_table;

#OPTIONAL
ALTER TABLE `your_table` ADD UNIQUE `unique_index` (`index1_id`, `index2_id`);

#OPTIONAL
DROP TABLE your_table_with_dupes;

1
外部キー制約のあるinnoDB設定がある場合は、うまく機能します。
magdmartin 2013

@magdmartin、しかし外部の制約はテーブルの削除を妨げませんか?
バシレフ2014

1
IGNOREステートメントは私にとってはうまくいきませんでした。これは500万件のレコードの重複排除に非常に役立ちました。乾杯。
Mauvis Ledford、2015

32

MySQLテーブルの重複を削除することは一般的な問題です。これは、一般に、事前に制約が欠落しているために重複を回避した結果です。しかし、この一般的な問題には通常、特定のニーズが伴います。特定のアプローチが必要です。アプローチは、たとえば、データのサイズ、保持する必要がある重複したエントリ(通常、最初または最後のエントリ)、保持するインデックスがあるかどうか、または追加の処理を実行するかどうかによって異なります。複製されたデータに対するアクション。

MySQL自体にもいくつかの特殊性があります。たとえば、テーブルのUPDATEを実行すると、FROM原因で同じテーブルを参照できないなどです(MySQLエラー#1093が発生します)。この制限は、一時テーブルで内部クエリを使用することで克服できます(上記のいくつかのアプローチで提案されています)。ただし、この内部クエリは、ビッグデータソースを処理する場合は特にうまく機能しません。

ただし、重複を削除するためのより良いアプローチが存在します。これは効率的で信頼性が高く、さまざまなニーズに簡単に適応できます。

一般的なアイデアは、新しい一時テーブルを作成し、通常は重複を回避するために一意の制約を追加し、重複を処理しながら、以前のテーブルから新しいテーブルにデータを挿入することです。このアプローチは、単純なMySQL INSERTクエリに依存し、それ以上の重複を避けるために新しい制約を作成し、重複を検索するために内部クエリを使用する必要性と、メモリに保持する必要がある一時テーブルをスキップします(したがって、大きなデータソースにも適合します)。

これは、それを実現する方法です。次の列を持つテーブルemployeeがあるとします。

employee (id, first_name, last_name, start_date, ssn)

重複するssn列を持つ行を削除し、最初に見つかったエントリのみを保持するには、次のプロセスに従います。

-- create a new tmp_eployee table
CREATE TABLE tmp_employee LIKE employee;

-- add a unique constraint
ALTER TABLE tmp_employee ADD UNIQUE(ssn);

-- scan over the employee table to insert employee entries
INSERT IGNORE INTO tmp_employee SELECT * FROM employee ORDER BY id;

-- rename tables
RENAME TABLE employee TO backup_employee, tmp_employee TO employee;

技術説明

  • ライン#1は、新たな作成tmp_eployeeのと全く同じ構造のテーブルを従業員テーブル
  • 2行目では、新しいtmp_eployeeテーブルにUNIQUE制約を追加して、重複を回避しています。
  • 行#3は、IDで元の従業員テーブルをスキャンし、重複したエントリを無視しながら、新しい従業員エントリを新しいtmp_eployeeテーブルに挿入します。
  • 行#4はテーブルの名前を変更するため、新しい従業員テーブルは重複なしですべてのエントリを保持し、以前のデータのバックアップコピーはbackup_employeeテーブルに保持されます。

このアプローチを使用して、1.6Mレジスタは200秒未満で6kに変換されました。

Chetan、このプロセスに従って、次のコマンドを実行することにより、すべての重複をすばやく簡単に削除し、UNIQUE制約を作成できます。

CREATE TABLE tmp_jobs LIKE jobs;

ALTER TABLE tmp_jobs ADD UNIQUE(site_id, title, company);

INSERT IGNORE INTO tmp_jobs SELECT * FROM jobs ORDER BY id;

RENAME TABLE jobs TO backup_jobs, tmp_jobs TO jobs;

もちろん、このプロセスをさらに変更して、重複を削除するときのさまざまなニーズに適応させることができます。次にいくつかの例を示します。

the最初のエントリではなく最後のエントリを保持するためのバリエーション

最初のエントリではなく、最後に複製されたエントリを保持する必要がある場合があります。

CREATE TABLE tmp_employee LIKE employee;

ALTER TABLE tmp_employee ADD UNIQUE(ssn);

INSERT IGNORE INTO tmp_employee SELECT * FROM employee ORDER BY id DESC;

RENAME TABLE employee TO backup_employee, tmp_employee TO employee;
  • 3行目では、ORDER BY id DESC句が最後のIDを残りのIDよりも優先させます。

found重複に対していくつかのタスクを実行するためのバリエーション、たとえば、見つかった重複をカウントする

場合によっては、見つかった重複エントリに対してさらに処理を実行する必要があります(重複のカウントを保持するなど)。

CREATE TABLE tmp_employee LIKE employee;

ALTER TABLE tmp_employee ADD UNIQUE(ssn);

ALTER TABLE tmp_employee ADD COLUMN n_duplicates INT DEFAULT 0;

INSERT INTO tmp_employee SELECT * FROM employee ORDER BY id ON DUPLICATE KEY UPDATE n_duplicates=n_duplicates+1;

RENAME TABLE employee TO backup_employee, tmp_employee TO employee;
  • 行#3で、新しい列n_duplicatesが作成されます
  • 4行目では、INSERT INTO ... ON DUPLICATE KEY UPDATEクエリを使用して、重複が見つかったときに追加の更新を実行します(この場合、カウンターを増やします)。INSERTINTO ... ON DUPLICATE KEY UPDATEクエリは次のようになります。見つかった重複に対して異なるタイプの更新を実行するために使用されます。

auto自動増分フィールドIDを再生成するためのバリエーション

自動インクリメンタルフィールドを使用する場合があります。インデックスをできるだけコンパクトに保つ​​ために、重複の削除を利用して、新しい一時テーブルで自動インクリメンタルフィールドを再生成できます。

CREATE TABLE tmp_employee LIKE employee;

ALTER TABLE tmp_employee ADD UNIQUE(ssn);

INSERT IGNORE INTO tmp_employee SELECT (first_name, last_name, start_date, ssn) FROM employee ORDER BY id;

RENAME TABLE employee TO backup_employee, tmp_employee TO employee;
  • 3行目では、テーブルのすべてのフィールドを選択する代わりに、IDフィールドがスキップされるため、DBエンジンは新しいフィールドを自動的に生成します。

✔その他のバリエーション

必要な動作に応じて、さらに多くの変更を行うこともできます。例として、次のクエリは、2番目の一時テーブルを使用して、1)最初のエントリではなく最後のエントリを保持します。2)見つかった重複のカウンターを増やす。また、3)以前のデータの場合と同じように入力順序を維持しながら、自動増分フィールドIDを再生成します。

CREATE TABLE tmp_employee LIKE employee;

ALTER TABLE tmp_employee ADD UNIQUE(ssn);

ALTER TABLE tmp_employee ADD COLUMN n_duplicates INT DEFAULT 0;

INSERT INTO tmp_employee SELECT * FROM employee ORDER BY id DESC ON DUPLICATE KEY UPDATE n_duplicates=n_duplicates+1;

CREATE TABLE tmp_employee2 LIKE tmp_employee;

INSERT INTO tmp_employee2 SELECT (first_name, last_name, start_date, ssn) FROM tmp_employee ORDER BY id;

DROP TABLE tmp_employee;

RENAME TABLE employee TO backup_employee, tmp_employee2 TO employee;

27

別の解決策があります:

DELETE t1 FROM my_table t1, my_table t2 WHERE t1.id < t2.id AND t1.my_field = t2.my_field AND t1.my_field_2 = t2.my_field_2 AND ...

4
これは、6か月前に提出した@rehriffの回答とどう違うのですか?
Lawrence Dol

@LawrenceDolもう少し読みやすくなっていると思います。また、私が答えたときの彼の答えは同じではなかったと思います。彼の答えは編集されたと思います。
モスタファ-T 2016年

1
うーん。レコード数が多くなかったのに、私には時間がかかりすぎました!
SuB

8

膨大な数のレコードを含む大きなテーブルがある場合、上記のソリューションは機能しないか、時間がかかりすぎます。次に、別のソリューションがあります

-- Create temporary table

CREATE TABLE temp_table LIKE table1;

-- Add constraint
ALTER TABLE temp_table ADD UNIQUE(title, company,site_id);

-- Copy data
INSERT IGNORE INTO temp_table SELECT * FROM table1;

-- Rename and drop
RENAME TABLE table1 TO old_table1, temp_table TO table1;
DROP TABLE old_table1;

6

私はSQLServerにこのクエリスニペットを持っていますが、ほとんど変更なしで他のDBMSで使用できると思います。

DELETE
FROM Table
WHERE Table.idTable IN  (  
    SELECT MAX(idTable)
    FROM idTable
    GROUP BY field1, field2, field3
    HAVING COUNT(*) > 1)

このクエリでは、重複する行のIDが最小の行は削除されないことを忘れていました。これが機能する場合は、次のクエリを試してください。

DELETE
FROM jobs
WHERE jobs.id IN  (  
    SELECT MAX(id)
    FROM jobs
    GROUP BY site_id, company, title, location
    HAVING COUNT(*) > 1)

グループの重複が3つ以上ある場合は機能しません。
OMGポニー

11
残念ながら、MySQLでは、削除するテーブルからの選択は許可されていませんERROR 1093: You can't specify target table 'Table' for update in FROM clause
Andomar

1
"You can't specify target table 'Table' for update in FROM..."エラーを解決するには、DELETE FROM Table WHERE Table.idTable IN ( SELECT MAX(idTable) FROM (SELECT * FROM idTable) AS tmp GROUP BY field1, field2, field3 HAVING COUNT(*) > 1)MySQLにテンポラリーテーブルを作成するように強制します。ただし、大規模なデータセットでは処理が非常に遅くなります...そのような場合は、Andomarのコードをお勧めします。
lepe 2016年

6

より速い方法は、一時的なテーブルに個別の行を挿入することです。削除を使用すると、800万行のテーブルから重複を削除するのに数時間かかりました。挿入と個別を使用すると、わずか13分で完了しました。

CREATE TABLE tempTableName LIKE tableName;  
CREATE INDEX ix_all_id ON tableName(cellId,attributeId,entityRowId,value);  
INSERT INTO tempTableName(cellId,attributeId,entityRowId,value) SELECT DISTINCT cellId,attributeId,entityRowId,value FROM tableName;  
TRUNCATE TABLE tableName;
INSERT INTO tableName SELECT * FROM tempTableName; 
DROP TABLE tempTableName;  

1
あなたの4行目は言うべきでTRUNCATE TABLE tableNameあり、5行目は言うべきですINSERT INTO tableName SELECT * FROM tempTableName;
サナ

5

理解しやすく、主キーなしで機能するソリューション:

1)新しいブール列を追加する

alter table mytable add tokeep boolean;

2)複製された列と新しい列に制約を追加します

alter table mytable add constraint preventdupe unique (mycol1, mycol2, tokeep);

3)ブール列をtrueに設定します。新しい制約のため、これは複製された行の1つでのみ成功します

update ignore mytable set tokeep = true;

4)tokeepとしてマークされていない行を削除する

delete from mytable where tokeep is null;

5)追加した列をドロップします

alter table mytable drop tokeep;

追加した制約を保持して、将来新しい重複が発生しないようにすることをお勧めします。


1
これは、受け入れられたソリューションが機能しなくなったmysql 5.7で本当にうまくいった
Robin31

5

DELETE JOINステートメントを使用して重複行を削除するMySQLは、重複行をすばやく削除するために使用できるDELETE JOINステートメントを提供します。

次のステートメントは、重複する行を削除し、最高のIDを保持します。

DELETE t1 FROM contacts t1
    INNER JOIN
contacts t2 WHERE
t1.id < t2.id AND t1.email = t2.email;

5

簡単な方法を見つけました。(最新に保つ)

DELETE t1 FROM tablename t1 INNER JOIN tablename t2 
WHERE t1.id < t2.id AND t1.column1 = t2.column1 AND t1.column2 = t2.column2;

4

すべてのケースでシンプルかつ高速:

CREATE TEMPORARY TABLE IF NOT EXISTS _temp_duplicates AS (SELECT dub.id FROM table_with_duplications dub GROUP BY dub.field_must_be_uniq_1, dub.field_must_be_uniq_2 HAVING COUNT(*)  > 1);

DELETE FROM table_with_duplications WHERE id IN (SELECT id FROM _temp_duplicates);

エラーコード:1055。SELECTリストの式#2がGROUP BY句になく、GROUP BY句の列に機能的に依存しない非集計列 'dub.id'が含まれています。これはsql_mode = only_full_group_byと互換性がありません
Swoogan

sql_modeを使用して「ハードコントロール」を無効にすることができます。stackoverflow.com/ questions / 23921117 / disable
only

4

これにより、タイトル、会社、サイトの値が同じ重複行が削除されます。最初の発生が保持され、残りはすべての重複が削除されます

DELETE t1 FROM tablename t1
INNER JOIN tablename t2 
WHERE 
    t1.id < t2.id AND
    t1.title = t2.title AND
    t1.company=t2.company AND
    t1.site_ID=t2.site_ID;

遅い(5w +行、ロック待機タイムアウト)が機能しました
yurenchen

3

私はグーグル「mysqlから重複を削除」するたびにこのページにアクセスし続けますが、InnoDB mysqlテーブルがあるため、私のIGNOREソリューションは機能しません

このコードはいつでもうまく機能します

CREATE TABLE tableToclean_temp LIKE tableToclean;
ALTER TABLE tableToclean_temp ADD UNIQUE INDEX (fontsinuse_id);
INSERT IGNORE INTO tableToclean_temp SELECT * FROM tableToclean;
DROP TABLE tableToclean;
RENAME TABLE tableToclean_temp TO tableToclean;

tableToclean =クリーンアップする必要があるテーブルの名前

tableToclean_temp =作成および削除された一時テーブル


2

このソリューションは、うつのテーブルに重複して移動し、別のものにユニーク

-- speed up creating uniques table if dealing with many rows
CREATE INDEX temp_idx ON jobs(site_id, company, title, location);

-- create the table with unique rows
INSERT jobs_uniques SELECT * FROM
    (
    SELECT * 
    FROM jobs
    GROUP BY site_id, company, title, location
    HAVING count(1) > 1
    UNION
    SELECT *
    FROM jobs
    GROUP BY site_id, company, title, location
    HAVING count(1) = 1
) x

-- create the table with duplicate rows
INSERT jobs_dupes 
SELECT * 
FROM jobs
WHERE id NOT IN
(SELECT id FROM jobs_uniques)

-- confirm the difference between uniques and dupes tables
SELECT COUNT(1)
AS jobs, 
(SELECT COUNT(1) FROM jobs_dupes) + (SELECT COUNT(1) FROM jobs_uniques)
AS sum
FROM jobs

なぜあなたは労働組合を取ったのSELECT * FROM jobs GROUP BY site_id, company, title, locationですか?
timctran 2015

2

バージョン8.0(2018)以降、MySQLはついにウィンドウ関数をサポートします

ウィンドウ関数は便利で効率的です。以下は、これらを使用してこの割り当てを解決する方法を示すソリューションです。

を使用ROW_NUMBER()して、サブクエリでcolumn1/column2グループ内のテーブル内の各レコードに位置を割り当てるために使用できますid。重複がない場合、レコードは行番号を取得し1ます。重複が存在する場合、昇順で番号が付けられますid(から始まる1)。

サブクエリでレコードに適切な番号が付けられると、外部クエリは行番号が1でないすべてのレコードを削除するだけです。

クエリ:

DELETE FROM tablename
WHERE id IN (
    SELECT id
    FROM (
        SELECT 
            id, 
            ROW_NUMBER() OVER(PARTITION BY column1, column2 ORDER BY id) rn
        FROM output
    ) t
    WHERE rn > 1
)

1

テーブル内の重複レコードを削除するには。

delete from job s 
where rowid < any 
(select rowid from job k 
where s.site_id = k.site_id and 
s.title = k.title and 
s.company = k.company);

または

delete from job s 
where rowid not in 
(select max(rowid) from job k 
where s.site_id = k.site_id and
s.title = k.title and 
s.company = k.company);

1
-- Here is what I used, and it works:
create table temp_table like my_table;
-- t_id is my unique column
insert into temp_table (id) select id from my_table GROUP by t_id;
delete from my_table where id not in (select id from temp_table);
drop table temp_table;

0

一意の列を持つレコードを複製するには、たとえばCOL1、COL2、COL3をレプリケートする必要はありません(テーブル構造で一意の3列を逃し、複数の重複するエントリがテーブルに作成されていると仮定します)。

DROP TABLE TABLE_NAME_copy;
CREATE TABLE TABLE_NAME_copy LIKE TABLE_NAME;
INSERT INTO TABLE_NAME_copy
SELECT * FROM TABLE_NAME
GROUP BY COLUMN1, COLUMN2, COLUMN3; 
DROP TABLE TABLE_NAME;
ALTER TABLE TABLE_NAME_copy RENAME TO TABLE_NAME;

希望は開発を助けます。


0

TL; TR;

この問題を解決するための詳細なチュートリアルは、mysqltutorial.orgにあります。サイトにあります。

MySQLで重複する行を削除する方法

3つの異なる方法で重複行を削除する方法が非常に明確に示されています

A)DELETE JOINステートメントの使用

B)中間テーブルを使用する

C)ROW_NUMBER()関数の使用

誰かのお役に立てば幸いです。


0

id行に主キーを追加するのを忘れているテーブルがあります。idにauto_incrementがありますが。しかし、ある日、データベースのmysql binログを再生して、重複する行を挿入します。

重複行を削除する

  1. 重複する一意の行を選択してエクスポートする

select T1.* from table_name T1 inner join (select count(*) as c,id from table_name group by id) T2 on T1.id = T2.id where T2.c > 1 group by T1.id;

  1. IDで重複する行を削除する

  2. エクスポートされたデータから行を挿入します。

  3. 次に、idに主キーを追加します


-2

削除するレコードをもう少し具体的にしたいので、これが私の解決策です:

delete
from jobs c1
where not c1.location = 'Paris'
and  c1.site_id > 64218
and exists 
(  
select * from jobs c2 
where c2.site_id = c1.site_id
and   c2.company = c1.company
and   c2.location = c1.location
and   c2.title = c1.title
and   c2.site_id > 63412
and   c2.site_id < 64219
)

-4

このコードから重複するレコードを簡単に削除できます。

$qry = mysql_query("SELECT * from cities");
while($qry_row = mysql_fetch_array($qry))
{
$qry2 = mysql_query("SELECT * from cities2 where city = '".$qry_row['city']."'");

if(mysql_num_rows($qry2) > 1){
    while($row = mysql_fetch_array($qry2)){
        $city_arry[] = $row;

        }

    $total = sizeof($city_arry) - 1;
        for($i=1; $i<=$total; $i++){


            mysql_query( "delete from cities2 where town_id = '".$city_arry[$i][0]."'");

            }
    }
    //exit;
}

3
これは非常に悪い形式です。データベースタスクはDBで実行する必要があります。データベースタスクは、php / mysql間でデータを絶えず送信するのではなく、はるかに高速です。
最大

-4

私はこれをテキストフィールドで行う必要があり、インデックスの100バイトの制限に遭遇しました。

列を追加し、フィールドのmd5ハッシュを実行し、変更を実行することで、これを解決しました。

ALTER TABLE table ADD `merged` VARCHAR( 40 ) NOT NULL ;
UPDATE TABLE SET merged` = MD5(CONCAT(`col1`, `col2`, `col3`))
ALTER IGNORE TABLE table ADD UNIQUE INDEX idx_name (`merged`);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.