web-dev-qa-db-ja.com

テーブルの1行のみを保持し、重複行を削除する方法は?

[名前]列に多くの重複があるテーブルがあります。それぞれに1行だけ保持したいと思います。

以下は重複を一覧表示していますが、重複を削除して保持する方法がわかりません。

SELECT name FROM members GROUP BY name HAVING COUNT(*) > 1;

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

16
Gulbahar

次の質問を参照してください: テーブルからの重複行の削除

そこからの適応された受け入れられた答え(これは私の答えなので、ここでは「盗難」はありません...):

一意のIDフィールドがあると仮定すると、簡単な方法でそれを行うことができます。IDを除いて同じであるが、名前に「最小ID」がないすべてのレコードを削除できます。

クエリの例:

DELETE FROM members
WHERE ID NOT IN
(
    SELECT MIN(ID)
    FROM members
    GROUP BY name
)

一意のインデックスがない場合は、自動増分の一意のインデックスを追加することをお勧めします。これは主に優れたデザインであるだけでなく、上記のクエリを実行できるためでもあります。

41
Roee Adler

一意のテーブルを新しいテーブルに選択し、古いテーブルを削除してから、一時テーブルの名前を変更して置き換えるほうが簡単でしょう。

#create a table with same schema as members
CREATE TABLE tmp (...);

#insert the unique records
INSERT INTO tmp SELECT * FROM members GROUP BY name;

#swap it in
RENAME TABLE members TO members_old, tmp TO members;

#drop the old one
DROP TABLE members_old;
4
Paul Dixon

重複を削除することが定期的なメンテナンスプロセスの一部である巨大なデータベースがあります。 DISTINCTを使用して一意のレコードを選択し、それらをTEMPORARY TABLEに書き込みます。 TRUNCATEの後、TEMPORARYデータをTABLEに書き戻します。

それはそれを行う1つの方法であり、STORED PROCEDUREとして機能します。

0
G Berdal

最初に、削除しようとしている行を確認したい場合。次に、それらを削除します。

with MYCTE as (
    SELECT DuplicateKey1
        ,DuplicateKey2 --optional
        ,count(*) X
    FROM MyTable
    group by DuplicateKey1, DuplicateKey2
    having count(*) > 1
) 
SELECT E.*
FROM MyTable E
JOIN MYCTE cte
ON E.DuplicateKey1=cte.DuplicateKey1
    AND E.DuplicateKey2=cte.DuplicateKey2
ORDER BY E.DuplicateKey1, E.DuplicateKey2, CreatedAt

完全な例 http://developer.azurewebsites.net/2014/09/better-sql-group-by-find-duplicate-data/

0
Lauri Lubi

一致したフィールドでテーブルを自分と結合し、一致しない行を削除できます

DELETE t1 FROM table_name t1 
LEFT JOIN tablename t2 ON t1.match_field = t2.match_field
WHERE t1.id <> t2.id;
0
AnyKey

delete dup row keep oneテーブルに重複行があり、一部の行には重複行がない可能性があり、テーブルに重複または単一の場合は1行保持します。テーブルから重複する名前を削除して1つ保持する必要がある場合、テーブルには2つの列IDと名前があります。私の終わりにその細かい作業このクエリを使用する必要があります。

DELETE FROM tablename
WHERE id NOT IN(

 SELECT id FROM
(
    SELECT MIN(id)AS id
    FROM tablename
    GROUP BY name HAVING 
    COUNT(*) > 1
)AS a )
AND id NOT IN(
(SELECT ids FROM
(
SELECT MIN(id)AS ids
    FROM tablename
    GROUP BY name HAVING 
    COUNT(*) =1
)AS a1
)
)

テーブルを削除する前に以下のスクリーンショットを参照してください。 ここに画像の説明を入力 テーブルを削除してからスクリーンショットを参照した後、このクエリはamitとakhilの重複行を削除し、1つのレコードを保持します(amitとakhil):

ここに画像の説明を入力

0
Akhil Singh

テーブルから重複レコードを削除する場合。

CREATE TABLE tmp SELECT lastname, firstname, sex
FROM user_tbl;
GROUP BY (lastname, firstname);

DROP TABLE user_tbl;

ALTER TABLE tmp RENAME TO user_tbl;
0
pappu kumar