Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2922 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [Résolu][MYSQL] lister les doublons + rapidement

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Résolu][MYSQL] lister les doublons + rapidement

n°1596125
dj3c1t
Posté le 06-08-2007 à 12:22:12  profilanswer
 

Bonjour,
 
J'ai un programme en Php pour gérer des contacts dans une base de données MySql.
L'une des fonctionnalités est de pouvoir lister les contacts qui ont le même email, pour éventuellement supprimer ou modifier ces contacts.
 
Dans la table contacts, j'ai un champ email, et je peux trouver les contacts en doublon sur l'email avec cette requete:
 

Code :
  1. SELECT * FROM contacts GROUP BY email HAVING COUNT(email) > 1


 
Mais cette requête ne me donne qu'un contact par email. Et j'ai besoin de récupérer tous les contacts qui ont un email qu'on retrouve ailleur dans la table.
 
J'utilise alors cette requête:
 

Code :
  1. SELECT * FROM contacts WHERE email IN ( SELECT email FROM contacts GROUP BY email HAVING COUNT(email) > 1 )


 
Là, ça marche.
Le problème, maintenant, c'est que dès que la table de contacts commence à devenir un peu grande (1000, 2000 contacts....), la requete est très longue à s'executer.
 
J'ai déjà remarqué ça, avec MySql, quand j'utilise un WHERE avec un IN suivi d'une requête interne....
Et je me demandais, donc, si y'avait moyen de faire sans passer par une reqête interne.
 
J'ai vu dans un autre thread que mysql proposait une fonction group_concat, qui pourrait marcher ici, mais ça m'embète un peu: pas sûr de retrouver ça si on change de SGBD...
 
Voilà, voilà... si quelqu'un a une idée ?
 
Merci d'avance pour votre aide.
Nicolas


Message édité par dj3c1t le 09-09-2007 à 19:29:55
mood
Publicité
Posté le 06-08-2007 à 12:22:12  profilanswer
 

n°1596133
TheRom_S
Posté le 06-08-2007 à 13:07:53  profilanswer
 

Je crois que si la requête met du temps, c'est parce qu'il refait la sous-requête à chaque fois (donc un traitement en N²)
Tu peux prendre les résultats de ta première requête (SELECT email FROM contacts GROUP BY email HAVING COUNT(email) > 1), créer une liste statique avec les valeurs des emails en php/java/... de la forme '("email1@truc.com","email2@...",...)' et t'en servir comme condition pour le IN de la seconde requête (SELECT * FROM contacts WHERE email IN (liste_statique))
 
Je sais pas si c'est idéal mais j'ai déjà eu de bons résultats en utilisant cette méthode


---------------
The Rom's, à votre service
n°1596201
dj3c1t
Posté le 06-08-2007 à 14:50:20  profilanswer
 

Nickel !!!
 
Comme j'étais pas sûr de la taille de ma liste statique, je suis passé par une table temporaire:
 

Code :
  1. CREATE TEMPORARY TABLE tmp_xxx AS SELECT email FROM contacts GROUP BY email HAVING COUNT(email) > 1


 
puis:
 

Code :
  1. SELECT contacts.* FROM contacts, tmp_xxx WHERE contacts.email=tmp_xxx.email


 
avec le nom de ma table temporaire (tmp_xxx) généré avec php pour un nom unique à chaque fois.
 
Et là.... punaise, ça va carrément plus vite qu'avec une sous-requête !
 
Merci beaucoup pour ta réponse, TheRom_s !

n°1596224
MagicBuzz
Posté le 06-08-2007 à 16:06:07  profilanswer
 

Quelle bouse infâme MySQL...
 
Il n'est pas du tout censé refaire la sous-requête à chaque fois...
 
Sinon, en plus propre :

Code :
  1. SELECT c1.*
  2. FROM contacts c1
  3. LEFT OUTER JOIN contacts c2 ON c2.id != c1.id AND c2.email = c1.email
  4. WHERE c2.id IS NOT NULL


 
Ca devrait donner le même résultat.


Message édité par MagicBuzz le 06-08-2007 à 17:50:51
n°1596272
dj3c1t
Posté le 06-08-2007 à 17:01:06  profilanswer
 

Héhé, oui, y'a sans doute des SGBD mieux conçus... ma foi.
 
interressante, en tout cas, ta requête.
'suis pas un virtuose du LEFT OUTER JOIN, mais là pour le coup ça m'intrigue...
 
 :jap:


Message édité par dj3c1t le 06-08-2007 à 17:36:28
n°1596318
MagicBuzz
Posté le 06-08-2007 à 17:51:17  profilanswer
 

ben en fait (logiquement) ça retourne les lignes où il existe un ID différent pour la même valeur de l'email.
 
c'est à tester, mais ça devrait marcher.

n°1596386
dj3c1t
Posté le 06-08-2007 à 20:09:28  profilanswer
 

oui, ça marche trés bien.
mais sur une table en particulier, j'obtenais pas le même nombre de résultats que quand je faisais une requête intermédiaire (avec une liste statique ou une table temporaire).
 
...
je viens de comprendre: ta requête marche impec pour les doublons au sens strict du terme.
je veux dire: si dans une table de contacts, un email est attribué soit à un contact soit à deux, alors c'est bon, la requête liste les contacts qui ont un email qu'on retrouve une fois ailleur (les doublons, donc).
 
mais si trois contacts ont le même email, on se retrouve avec deux fois le même contact (même identifiant) dans le résultats.
si quatre contacts ont le même email, chacun de ces contacts se retrouve trois fois dans le résultat, etc.
 
Cette requête a cependant l'avantage d'être rapide et de se faire en une seule fois, et on doit pouvoir s'en sortir en faisant un distinct sur l'id... quelque chose comme :
 

Code :
  1. SELECT DISTINCT(c1.id), c1.*
  2. FROM contacts c1 LEFT OUTER JOIN contacts c2
  3. ON c2.id != c1.id AND c2.email = c1.email
  4. WHERE c2.id IS NOT NULL;


 
bon, c'est à paufiner après, parce qu'on se retrouve du coup avec deux colones "id"... donc en précisant par exemple champ par champ se qui doit être récupéré...
 
Merci bien en tout cas pour vos réponses !
Les deux solutions sont vraiment beaucoup plus rapides qu'avec une sous-requête !


Message édité par dj3c1t le 07-08-2007 à 11:51:26

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [Résolu][MYSQL] lister les doublons + rapidement

 

Sujets relatifs
Résolu[MYSQL] Soucis avec matching sur requete moteur de recherche
Trigger sur la base et non sur une table [resolu][Résolu] Problème avec les variables de session
MysqlDifférence d'interpretation IE/firefox sur blog
[MySQL] probleme de clé etrangereConnexion à MySQL
[Résolu] Erreur AJAXProbleme avec DISTINCT / MySQL
Plus de sujets relatifs à : [Résolu][MYSQL] lister les doublons + rapidement


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR