J'ai une table dans une base de données PostgreSQL 8.3.8, qui n'a pas de clé/contrainte sur elle, et a plusieurs lignes avec exactement les mêmes valeurs.
Je souhaite supprimer tous les doublons et ne conserver qu'une copie de chaque ligne.
Une colonne en particulier (nommée "clé") peut être utilisée pour identifier les doublons (c’est-à-dire qu’il ne doit exister qu’une entrée pour chaque "clé" distincte).
Comment puis-je faire ceci? (idéalement avec une seule commande SQL) La vitesse n’est pas un problème dans ce cas (il n’ya que quelques lignes).
DELETE FROM dupes a
WHERE a.ctid <> (SELECT min(b.ctid)
FROM dupes b
WHERE a.key = b.key);
Une solution plus rapide est
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
C'est rapide et concis:
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
Voir aussi ma réponse à Comment supprimer des lignes en double sans identifiant unique qui inclut plus d'informations.
J'ai essayé ceci:
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);
fourni par Postgres wiki:
Je devais créer ma propre version. La version écrite par @a_horse_with_no_name est beaucoup trop lente sur ma table (21 millions de lignes). Et @rapimo ne supprime tout simplement pas les doublons.
Voici ce que j'utilise sur 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);
Je voudrais utiliser une table temporaire:
create table tab_temp as
select distinct f1, f2, f3, fn
from tab;
Ensuite, supprimez tab
et renommez tab_temp
en tab
.
Cela a bien fonctionné pour moi. J'ai eu une table, termes, qui contenait des valeurs en double. Exécution d'une requête pour remplir une table temporaire avec toutes les lignes en double. Ensuite, j'ai exécuté l'instruction a delete avec ces identifiants dans la table temporaire. valeur est la colonne qui contenait les doublons.
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)