2010-07-21 7 views
0

J'ai déjà 80 millions d'enregistrements insérés dans une table, mais je dois m'assurer que quelques colonnes sont communes. Cependant, les colonnes contiennent déjà des données non uniques, donc ALTER TABLE ne fonctionne pas. Je voudrais une requête qui me permette de supprimer facilement des enregistrements non uniques, en conservant l'un d'entre eux, ou un qui me permettra de charger les données de la table en cours dans une nouvelle, tout en filtrage pour l'unicité.Application de l'unicité sur une colonne de table PostgreSQL après l'insertion de valeurs non uniques

+0

Avez-vous un critère pour choisir la ligne à conserver et celle à rejeter lorsque l'unicité est violée pour ces colonnes? –

+0

Oui, une colonne de date. Je garderais les enregistrements les plus récents. Si ceux-ci sont également en double pour une raison quelconque, l'un ou l'autre peut y aller. – ehsanul

Répondre

5

La requête que vous cherchez est:

select distinct on (my_unique_1, my_unique_2) * from my_table; 

Cette sélectionne une ligne pour chaque combinaison de colonnes dans les distinct on. En fait, c'est toujours la première ligne. Il est rarement utilisé sans order by puisqu'il n'y a pas d'ordre fiable dans lequel les lignes sont retournées (et donc quelle est la première).

Combiné avec order by vous pouvez choisir quelles lignes sont la première (ce qui laisse les lignes avec le plus grand last_update_date):

select distinct on (my_unique_1, my_unique_2) * 
from my_table order by my_unique_1, my_unique_2, last_update_date desc; 

Maintenant, vous pouvez sélectionner ceci dans une nouvelle table:

create table my_new_table as 
select distinct on (my_unique_1, my_unique_2) * 
from my_table order by my_unique_1, my_unique_2, last_update_date desc; 

Ou vous pouvez l'utiliser pour supprimer, en supposant que row_id est une clé primaire:

delete from my_table where row_id not in (
    select distinct on (my_unique_1, my_unique_2) row_id 
    from my_table order by my_unique_1, my_unique_2, last_update_date desc); 
+0

+1 DISTINCT ON est une fonctionnalité PostgreSQL très pratique – leonbloy

+0

A propos de "la première ligne": Sans ORDER BY, il n'y a aucun moyen de dire quelle ligne reviendra en premier, donc la "première ligne" est un terme trompeur comme vous pouvez pas toujours le même résultat. Un DISTINCT ON est pratiquement inutile sans clause ORDER BY. –

+0

Merci, mis à jour pour rendre cela plus explicite. –

Questions connexes