On Mon, Jan 27, 2003 at 06:43:49PM +0100, Thierry Lombardot wrote:

> probleme est connu. J'ai une cle priaire sur "id" pour une certaine 
> table, mais des entrees identiques ont ete introduites avec differentes 
> "id" et je voudrais m'en debarasser. Je n'ai pas tres envie d'ecrire un 

Si cela gêne, alors peut-être que la structure de la base de données
aurait dû être complétée avec une vérification de doublon.

Par exemple:

CREATE TABLE test (id SERIAL NOT NULL,
                   nom TEXT NOT NULL,
                   commentaire TEXT NOT NULL,
                   PRIMARY KEY(id), UNIQUE(id));

pourrait être complété, si l'on sait que `nom' sera forcément unique
(mais attention!):

    UNIQUE(nom)

On peut aussi spécifier l'unicité sur plusieurs champs, comme par
exemple:

   CREATE TABLE test (id SERIAL NOT NULL,
                      prenom TEXT NOT NULL,
                      nom TEXT NOT NULL,
                      numero_avs TEXT NOT NULL,
                      commentaire TEXT NOT NULL,
                      PRIMARY KEY(id), UNIQUE(id),
                      UNIQUE(numero_avs),
                      UNIQUE(prenom, nom));

De nouveau il faut être sûr que dans le cadre considéré `prénom, nom'
est unique. Donner un exemple réel est recommandé.

Dans notre cas, si l'on suppose que l'on a créé cette table en oubliant
la condition UNIQUE(numero_avs), on pourrait faire comme suit:

   1. supprimer les doublons (on suppose que si le numéro AVS est le
      même, on oublie les autres informations sauf pour le premier qui vient.
      Vérifier que cela respecte la sémantique des données).

      Effacer les doublons:

         -- Idée rapide: est un doublon un enregistrement dont
         -- l'id est supérieur au plus petit id, pour le même numéro
         -- AVS.

         DELETE FROM test
         WHERE id IN (SELECT id FROM test t1
                      WHERE t1.id IN (SELECT t1.id FROM test t2
                                      GROUP BY t2.numero_avs, t2.id
                                      HAVING (t1.id > MIN(t2.id))
                                             AND (t1.numero_avs
                                                  = t2.numero_avs)));

         PS: je n'ai pas trop réfléchi alors je vous laisse
             simplifier / améliorer cette requête.

   2. créer l'index unique.

      CREATE UNIQUE INDEX numero_avs_index
         ON test (numero_avs);

PS: dans ce qui précède j'utilise la syntax PostgreSQL, à vous
    d'adapter. Notamment je ne sais pas si MySQL supporte déjà
    les requêtes imbriquées. Sinon il faudra passer par des
    tables temporaires.

--
http://www-internal.alphanet.ch/linux-leman/ avant de poser
une question. Ouais, pour se désabonner aussi.

Répondre à