Recherche de doublons

Mammouth du PHP | 545 Messages

16 févr. 2008, 12:01

Bonjour,

Je serais intéressé de savoir s'il existe une requête à exécuter pour mettre en évidence les doubles entrées dans PHPMyAdmin.

Voici comment ma table est construite:

Code : Tout sélectionner

DROP TABLE IF EXISTS `jos_classement_chang`; CREATE TABLE `jos_classement_chang` ( `id` int(11) NOT NULL auto_increment, `club_id` int(11) NOT NULL default '0', `participant_id` int(11) NOT NULL default '0', `annee` year(4) default NULL, `dossard` smallint(5) unsigned NOT NULL default '0', `categorie_id` tinyint(3) unsigned NOT NULL default '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=1759 DEFAULT CHARSET=latin1 AUTO_INCREMENT=1759 ;
Et le test du doublon est possible sur le dossard pour une année données ... pouvez-vous m'aider si c'est possible ?

Merci
Sebe

Pour moi, le PHP est une nouvelle aventure qui a commencée fin octobre 2005 ... c'est plus exitant que le HTML!

Modérateur PHPfrance
Modérateur PHPfrance | 7636 Messages

16 févr. 2008, 14:01

Une requête qui compte [COUNT()] avec une restriction à une année donnée [ WHERE annee = ] et un groupement [ GROUP BY ] sur le dossard.

Si ce nombre renvoie plus de 1 alors doublon

Plus qu'à traduire en requête :)

/!\ Avant de poster se documenter et rechercher.
Qui ne sait pas rendre un service n'a pas le droit d'en demander.
MaBrute

ViPHP
ViPHP | 4039 Messages

16 févr. 2008, 14:05

hmm.. avec un group by ça doit coller:

quelque chôse comme ceci :

Code : Tout sélectionner

select * from (select dossard,count(*) as nombre from jos_classement_chang group by dossard) as a where nombre > 1;
mais il doit y avoir moyen de mieux faire.
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Mammouth du PHP | 545 Messages

16 févr. 2008, 14:10

Juste une question avant d'essayer ... dois-je tester cela pour chaque dossard ?

Merci pour vos réponses
Sebe

Pour moi, le PHP est une nouvelle aventure qui a commencée fin octobre 2005 ... c'est plus exitant que le HTML!

Modérateur PHPfrance
Modérateur PHPfrance | 7636 Messages

16 févr. 2008, 14:21

Ben.. teste :)

Le GROUP BY te renverras une série d'enregistrements...

Si tu ne veux que les doublons un HAVING sur l'élément COUNT() peut s'ajouter au reste.

/!\ Avant de poster se documenter et rechercher.
Qui ne sait pas rendre un service n'a pas le droit d'en demander.
MaBrute

ViPHP
ViPHP | 5924 Messages

16 févr. 2008, 14:27

Ou alors un :

Code : Tout sélectionner

SELECT dossard, annee FROM jos_classement_chang c1 JOIN jos_classement_chang c2 ON c1.dossard = c2.dossard AND c1.annee = c2.annee AND c1.id<>c2.id;
Mais si c'est pour interdire les doublon sur une année, tu devrais utiliser une clé unique ou primaire sur le couple (dossard, annee).

Mammouth du PHP | 545 Messages

16 févr. 2008, 14:37

Salut,
Mais si c'est pour interdire les doublon sur une année, tu devrais utiliser une clé unique ou primaire sur le couple (dossard, annee).
En faite, j'ai récupéré des fichiers csv que j'ai commencé à Uploader à la mano et je me rends compte qu'il y a des doublons ... ce serait simplement pour les rechercher afin de les mettre en évidence ! Je choisirai de les garder ou de les effacer. Seulement, je ne cherche pas un code php mais une requête à coller dans PHPMy Admin.

Merci pour tout !
Sebe

Pour moi, le PHP est une nouvelle aventure qui a commencée fin octobre 2005 ... c'est plus exitant que le HTML!

ViPHP
ViPHP | 5924 Messages

16 févr. 2008, 14:53

J'entend bien, mais une fois que tu les as trouvé avec l'une des requètes que nous t'avons donné, si jamais tu décides de les supprimer, normalement avec ca (après une sauvegarde):

Code : Tout sélectionner

DELETE jos_classement_chang FROM jos_classement_chang class WHERE jos_classement_chang.dossard = class.dossard AND jos_classement_chang.annee = class.annee AND jos_classement_chang.id<>class.id;
alors il vaudrait mieux ensuite fixer une clé appropriée sur les champs suscités pour éviter que le problème ne se reproduise…

Mammouth du PHP | 545 Messages

16 févr. 2008, 15:59

J'ai travaillé à la mano et j'ai ensuite fait ce qu'il m'avait été recommandé:
Mais si c'est pour interdire les doublon sur une année, tu devrais utiliser une clé unique ou primaire sur le couple (dossard, annee).
J'ai du relancer la procédure plusieurs fois car il y avait encore quelques doublons !

Merci pour tout !
Sebe

Pour moi, le PHP est une nouvelle aventure qui a commencée fin octobre 2005 ... c'est plus exitant que le HTML!

ViPHP
ViPHP | 5924 Messages

16 févr. 2008, 16:16

Si tu exportes la structure de ta table sous forme sql, ca donne quoi maintenant ?

Mammouth du PHP | 545 Messages

16 févr. 2008, 16:42

Si tu exportes la structure de ta table sous forme sql, ca donne quoi maintenant ?
Ceci:

Code : Tout sélectionner

CREATE TABLE `jos_classement_chang` ( `id` int(11) NOT NULL auto_increment, `club_id` int(11) NOT NULL default '0', `participant_id` int(11) NOT NULL default '0', `annee` year(4) default NULL, `dossard` smallint(5) unsigned NOT NULL default '0', `categorie_id` tinyint(3) unsigned NOT NULL default '0', PRIMARY KEY (`id`), UNIQUE KEY `doublon` (`annee`,`dossard`) ) ENGINE=MyISAM AUTO_INCREMENT=2714 DEFAULT CHARSET=latin1 AUTO_INCREMENT=2714 ;
Est-ce correcte
Sebe

Pour moi, le PHP est une nouvelle aventure qui a commencée fin octobre 2005 ... c'est plus exitant que le HTML!

ViPHP
ViPHP | 5924 Messages

16 févr. 2008, 17:15

C'est presque parfait.
En l'occurence l'idéal aurait été aussi de mettre des index. Pour les index, on en met sur les champs les plus utilisés dans les clauses WHERE, ORDER BY, GROUP BY, …, les clauses pour lesquelles un classement serait utile.
C'est à dire que si tu fais un :

Code : Tout sélectionner

SELECT dossard FROM table WHERE id='5';
Que les dossards soient en ordre ou non, ca ne changera rien pour lui, puisqu'il recherche en fonction de l'id. Par contre, avec une requète de ce style :

Code : Tout sélectionner

SELECT club FROM table WHERE dossard='5';
Si les dossards sont dans un certain ordre, la recherche se fera beaucoup plus vite.

Après, c'est à toi, en fonction des requètes que tu utilises, de voir pour quelles colonnes une indexation serait nécessaire. A savoir que tu auras un "classement" par index, et qu'un index sur plusieurs champs classe le premier champ, et pour les valeurs égales, fait un nouveau classement selon le second champ…

Au passage, très important, la clé primaire (ici id), est indexée par défaut, il est inutile de placer un index dessus. Donc si tu utilises essentiellement le champ id dans tes requètes, tu peux te passer des index.