Удаление дубликатов записей в PostgreSQL



У меня есть таблица в базе данных PostgreSQL 8.3.8, которая не имеет ключей/ограничений на нее и имеет несколько строк с точно такими же значениями.



Я хотел бы удалить все дубликаты и сохранить только 1 копию каждой строки.



существует один столбец, в частности (с именем "ключ"), который может быть использован для идентификации дубликатов (т. е. должна существовать только одна запись для каждого отдельного"ключа").



Как я могу это сделать? (в идеале с одной командой SQL )
Скорость не проблема в этом случае (есть только несколько строк).

1095   8  

8 ответов:

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

более быстрое решение

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

это быстро и лаконично:

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

см. Также мой ответ на как удалить повторяющиеся строки без уникального идентификатора который включает в себя дополнительную информацию.

Я попытался это:

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:

https://wiki.postgresql.org/wiki/Deleting_duplicates

Я должен создать свою собственную версию. Версия, написанная @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);

Я бы использовал временную таблицу:

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

затем удалить tab переименовать tab_temp на tab.

Это хорошо работало для меня. У меня была таблица, термины, которые содержали повторяющиеся значения. Выполнил запрос для заполнения временной таблицы всеми повторяющимися строками. Затем я запустил инструкцию a delete с этими идентификаторами во временной таблице. значение-это столбец, содержащий дубликаты.

        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)

РАБОТАЕТ КАК ДЛЯ ОБЫЧНОГО 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

и

первый запрос гарантирует, что если у вас есть резервная/временная таблица исходной таблицы, содержащей дубликаты, то сначала удалите эту таблицу.

2-й запрос, создает новую таблицу (временную / резервную) таблицу с уникальными записями в исходной таблице, содержащей дубликат, поэтому новый временная таблица совпадает с исходной таблицей за вычетом повторяющихся записей.

3-й запрос усекает или опустошает исходную таблицу.

4-й запрос вставляет или копирует все уникальные записи во временной таблице в исходную таблицу, которая была недавно усечена (поэтому не имеет данных). После выполнения этого запроса исходная таблица будет заполнена уникальными данными, которые были во временной таблице.

5-й запрос, удаляет/удаляет ненужные временная таблица.

таким образом, конечный результат состоит в том, что исходная таблица имеет только уникальные записи и никаких дубликатов.

Comments

    Ничего не найдено.