PostgreSQLの重複レコードを削除する

duplicates postgresql sql
PostgreSQLの重複レコードを削除する

PostgreSQL 8.3.8データベースにテーブルがあり、キー/制約がなく、まったく同じ値を持つ複数の行があります。

すべての重複を削除し、各行のコピーを1つだけ保持したいと思います。

重複を識別するために使用できる(「キー」という名前の)特に1つの列があります。 個別の「キー」ごとに1つのエントリのみが存在する必要があります)。

これどうやってするの? (理想的には単一のSQLコマンドで)この場合、速度は問題になりません(数行しかありません)。

  74  26


ベストアンサー

より高速なソリューションは

DELETE FROM dups a USING (
      SELECT MIN(ctid) as ctid, key
        FROM dups
        GROUP BY key HAVING COUNT(*) > 1
      ) b
      WHERE a.key = b.key
      AND a.ctid <> b.ctid

115


DELETE FROM dupes a
WHERE a.ctid <> (SELECT min(b.ctid)
                 FROM   dupes b
                 WHERE  a.key = b.key);

56


これは高速で簡潔です。

DELETE FROM dupes T1
    USING   dupes T2
WHERE   T1.ctid < T2.ctid  -- delete the older versions
    AND T1.key  = T2.key;  -- add more columns if needed

詳細については、https://stackoverflow.com/a/46775289/968244 [一意の識別子なしで重複する行を削除する方法]での私の回答も参照してください。

28


私はこれを試しました:

DELETE FROM tablename
WHERE id IN (SELECT id
              FROM (SELECT id,
                             ROW_NUMBER() OVER (partition BY column1, column2, column3 ORDER BY id) AS rnum
                     FROM tablename) t
              WHERE t.rnum > 1);

Postgres wikiにより提供:

13


独自のバージョンを作成する必要がありました。 @a_horse_with_no_nameによって記述されたバージョンは、テーブル(21M行)で非常に遅いです。 また、@ rapimoは重複を削除しません。

PostgreSQL 9.5で使用するものは次のとおりです。

DELETE FROM your_table
WHERE ctid IN (
  SELECT unnest(array_remove(all_ctids, actid))
  FROM (
         SELECT
           min(b.ctid)     AS actid,
           array_agg(ctid) AS all_ctids
         FROM your_table b
         GROUP BY key1, key2, key3, key4
         HAVING count(*) > 1) c);

6


私は一時テーブルを使用します:

create table tab_temp as
select distinct f1, f2, f3, fn
  from tab;

次に、「tab」を削除し、「tab_temp」の名前を「tab」に変更します。

4


これは私にとってはうまくいった。 重複する値を含むテーブル、用語がありました。 クエリを実行して、すべての重複行を一時テーブルに追加します。 次に、一時テーブルにこれらのIDを指定してdeleteステートメントを実行しました。 valueは、重複を含む列です。

        CREATE TEMP TABLE dupids AS
        select id from (
                    select value, id, row_number()
over (partition by value order by value)
    as rownum from terms
                  ) tmp
                  where rownum >= 2;

delete from [table] where id in (select id from dupids)

0


通常のSQLとPOSTGRESQLの両方で動作します(AWS REDSHIFTでも動作します)

DROP TABLE IF EXISTS backupOfTheTableContainingDuplicates;

CREATE TABLE aNewEmptyTemporaryOrBackupTable
AS SELECT DISTINCT * FROM originalTableContainingDuplicates;

TRUNCATE TABLE originalTableContainingDuplicates;

INSERT INTO originalTableContainingDuplicates SELECT * FROM
aNewEmptyTemporaryOrBackupTable ;

DROP TABLE aNewEmptyTemporaryOrBackupTable ;

上記のSQLスクリプトの説明

So,

最初のクエリでは、元のテーブルのバックアップ/一時テーブルに重複が含まれている場合、最初にそのテーブルを削除します。

2番目のクエリは、重複を含む元のテーブルに一意のエントリを持つ新しいテーブル(一時/バックアップ)テーブルを作成します。したがって、新しい一時テーブルは、重複エントリの元のテーブルMINUSと同じです。

3番目のクエリは、元のテーブルを切り捨てるか、空にします。

4番目のクエリは、一時テーブルのすべての一意のエントリを、最近切り捨てられた元のテーブルに挿入またはコピーします(つまり、データはありません)。 このクエリが実行された後、元のテーブルには、一時テーブルにあった一意のデータが入力されます。

5番目のクエリは、不要な一時テーブルを削除/削除します。

したがって、最終結果は、元のテーブルには一意のエントリのみがあり、重複はありません。

-1


タイトルとURLをコピーしました