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

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  suprimer doublons sauf celui d'un min absolu

 

Sujet(s) à lire :
 

 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

suprimer doublons sauf celui d'un min absolu

n°2217378
maestro130​3
Posté le 24-01-2014 à 02:19:13  profilanswer
 

bonjour,
dans une table j'ai des 'doublons' que je veux supprimer sauf celui ayant la plus petite valeur.par exemple je prend le cas de 2 doublons:
id ,4, 2, 35
id ,11, 1, 4
 
je veux supprimer la ligne qui ne contient pas 1 qui est la plus petite valeur cad
garder seulement id ,11, 1, 4 car 1 est le min de 4,2, 35,11, 1, 4
 
ET si j'ai les 3 enregistrements
 
id ,4, 2, 35
id ,11, 1, 4
id ,0, 1, 9
 
je supprime tout sauf id ,0, 1, 9 car 0 est le min des valeurs (4, 2, 35 ,11, 1, 4 ,0, 1, 9)
 
Est ce possible avec une simple requête mysql
 
Merci

mood
Publicité
Posté le 24-01-2014 à 02:19:13  profilanswer
 

n°2217485
lasnoufle
La seule et unique!
Posté le 24-01-2014 à 16:38:48  profilanswer
 

Salut
 
Je connais peu MySql mais une recherche rapide sur Google semble montrer qu'il n'y a pas de fonction pour decouper une chaine de caracteres; et si j'ai bien compris ce que tu demandes (car les champs a ta disposition, par exemple, ne sont pas tres clairs), ca va forcement bloquer a cause de ca.
 
Du coup "simple requete MySql" non. Il va falloir passer par un algo, donc par exemple declarer une procedure MySql, ou le faire en PHP, etc.
 
A+
G


---------------
C'était vraiment très intéressant.
n°2217510
maestro130​3
Posté le 24-01-2014 à 22:56:24  profilanswer
 


Bonjour  
Ce qui bloque est la requête ou les requêtes SQL qui me permettent d'effectuer cette tâche: je sais juste comment avoir le min des 3 champs mais seulement sur un enregistrement, genre

Code :
  1. least(c1,c2,c3)


Quant à comparer ce Min avec les Mins de tous les  autres enregistrements qui partagent le même ID; puis tirer l'enregistrement élu pour le garder en supprimant tous les autres, je n'arrive pas à formuler ça.
 
Par ailleurs MySQL supporte la fonction  

Code :
  1. substring(chaine,position,nb_caractères)


mais je ne pense pas qu'elle puisse être d'une grande utilité dans ma situation.
 
Enfin pour être plus précis sur le problème voici une autre manière de l'exposer:
les enregistrements n'ont de commun que le champ ID et cet ID n'est pas unique, la clé est un autoincrement.

Code :
  1. cle  ID C1  C2  C3
  2. ------------------
  3. 1234, id ,4, 2, 35
  4. 234, id ,11, 1, 4
  5. 6532, id ,0, 1, 9


 
Les champs c1, c2 et c3 sont des coûts.
 
La requête doit supprimer tous les enregistrements sauf
 

Code :
  1. 6532, id ,0, 1, 9


 
car  il contient 0 qui est le minimum absolu de tous les coûts ayant ID en commun.
 
Merci d'avance

n°2217513
lasnoufle
La seule et unique!
Posté le 25-01-2014 à 03:20:51  profilanswer
 

Tu veux dire que C1, C2 et C3 sont des champs separes? Si c'est le cas, du coup c'est possible. Un truc du genre:
 

DELETE FROM table WHERE cle NOT IN (
  SELECT t.cle
  FROM table t
  JOIN (
    SELECT id, MIN(min_local) as min_global
    FROM (
      SELECT id, LEAST(c1,c2,c3) as min_local
      FROM table
    )
  ) min_value ON min_value.id = t.id AND min_value.min_global = LEAST(t.c1,t.c2,t.c3)
)


Par contre si un ID a plusieurs lignes avec le cout minimum, ca les gardera toutes - a toi de voir si ca peut arriver, si c'est genant, et comment tu veux choisir quelle ligne garder.


---------------
C'était vraiment très intéressant.
n°2217534
maestro130​3
Posté le 25-01-2014 à 13:29:12  profilanswer
 

Merci beaucoup de cette réponse que je viens de tester mais qui m'a donné des erreurs qui sont certainement dues à mon incompréhension  ds la requête (je maîtrise pas encore les alias  :ouch: )
 
ma table s'appelle

Code :
  1. couts

et la clé s'appelle

Code :
  1. serie

, voici ce que j'ai écris
 

Code :
  1. DELETE FROM couts WHERE serie NOT IN (
  2.   SELECT t.serie
  3.   FROM table t
  4.   JOIN (
  5.     SELECT id, MIN(min_local) as min_global
  6.     FROM (
  7.       SELECT id, LEAST(c1,c2,c3) as min_local
  8.       FROM couts
  9.     )
  10.   ) min_value ON min_value.id = t.id AND min_value.min_global = LEAST(t.c1,t.c2,t.c3)
  11. )


 
Il me renvoie une erreur de syntaxe.
 
Est ce qu'il te semble que j'ai bien adapté ta requête au nom de ma table couts et à la clé serie?
 
Toutes mes excuses pour mon ignorance des ALIAS et merci d'avance
 

n°2217546
torwood3
Posté le 25-01-2014 à 19:38:05  profilanswer
 

Bonjour,
 
esaye :  

Code :
  1. DELETE FROM couts WHERE serie NOT IN (
  2.       SELECT t.serie
  3.       FROM couts t
  4.       JOIN (
  5.         SELECT id, MIN(min_local) as min_global
  6.         FROM (
  7.           SELECT id, LEAST(c1,c2,c3) as min_local
  8.           FROM couts
  9.         )
  10.       ) min_value ON min_value.id = t.id AND min_value.min_global = LEAST(t.c1,t.c2,t.c3)
  11.     )


Message édité par torwood3 le 25-01-2014 à 19:39:06

---------------
"La valeur d'un homme tient dans sa capacité à donner et non dans sa capacité à recevoir." Albert Einstein / "Dans la nature, tout a toujours une raison. Si tu comprends cette raison, tu n'as plus besoin de l'expérience." Léonard De Vinci
n°2217550
maestro130​3
Posté le 25-01-2014 à 22:50:45  profilanswer
 

Bonjour lasnoufle, merci torwood3,  
Merci de cette requête et de toute la peine que vous vous donnez pour moi. J'ai testé la requête précédente et voici l'erreur qu'il me sort :
 

Code :
  1. #1248 - Every derived table must have its own alias


 
Merci infiniment

n°2217575
lasnoufle
La seule et unique!
Posté le 26-01-2014 à 17:53:20  profilanswer
 

Re

 

Comme je disais, je connais pas trop mysql, mais d'apres google, ca a l'air d'etre une erreur "basique": visiblement, il faut toujours que les sous-requetes aient un alias en mysql.
Du coup, en partant de la reponse de torwood3, et en ajoutant un alias dans la sous-requete la plus a l'interieur:
   

DELETE FROM couts WHERE serie NOT IN (
          SELECT t.serie
          FROM couts t
          JOIN (
            SELECT id, MIN(min_local) as min_global
            FROM (
              SELECT id, LEAST(c1,c2,c3) as min_local
              FROM couts
            ) alias_quelconque
          ) min_value ON min_value.id = t.id AND min_value.min_global = LEAST(t.c1,t.c2,t.c3)
        )


Message édité par lasnoufle le 26-01-2014 à 17:53:55

---------------
C'était vraiment très intéressant.
n°2217604
maestro130​3
Posté le 26-01-2014 à 23:36:07  profilanswer
 

Bonjour lasnoufle, bonjour à tous,
 
Merci beaucoup de cette réponse qui -même si tu n'es pas un spécialiste de MySQL- me tirera certainement d'affaire, car elle fait effectivement disparaître l'erreur et surtout m'apprend quelque chose d'important pour l'avenir avec ce SGBD fabuleux qu'est MySQL.
 
Il subsite juste le message d'erreur qui suit:

Code :
  1. #1093 - You can't specify target table 'couts' for update in FROM clause


 
Ce qui m'intrigue c'est qu'il n'y a pourtant pas d'instruction update pour la table couts.
 
Merci d'avance.

n°2217705
lasnoufle
La seule et unique!
Posté le 27-01-2014 à 15:50:57  profilanswer
 

Interessant. Le DELETE est vu comme un UPDATE je suppose, et on dirait une "limitation" (a defaut d'un meilleur mot) de MySql: la requete retire des lignes de la table cout tout en utilisant cette meme table pour choisir les lignes a retirer, et on dirait que MySql ne "sait" pas gerer ca: si une ligne est retiree, doit-elle encore servir dans le calcul pour choisir celles restantes a retirer? Du coup, MySql empeche completement ce cas de figure d'arriver. Il y a peut-etre un parametre systeme pour changer ca...

 

Ca veut dire que en l'etat, tu ne vas pas pouvoir faire ca en une seule requete - au minimum, il va te falloir deux etapes: une pour calculer les lignes a garder (ou a enlever) et stocker la liste, et une pour faire le DELETE a partir de ta liste (et du coup, sans utiliser directement la table couts lors du delete).

 

Tu peux utiliser une table intermediaire pour ca, par exemple:

CREATE TABLE temp_couts_a_garder AS
SELECT t.serie
          FROM couts t
          JOIN (
            SELECT id, MIN(min_local) as min_global
            FROM (
              SELECT id, LEAST(c1,c2,c3) as min_local
              FROM couts
            ) alias_quelconque
          ) min_value ON min_value.id = t.id AND min_value.min_global = LEAST(t.c1,t.c2,t.c3);

(la syntaxe a peut-etre besoin d'etre ajustee)
puis

DELETE FROM couts WHERE serie NOT IN (SELECT serie FROM temp_couts_a_garder);

Puis evidemment, detruis ta table intermediaire.

DROP TABLE temp_couts_a_garder;


A+


Message édité par lasnoufle le 27-01-2014 à 15:52:40

---------------
C'était vraiment très intéressant.

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

  suprimer doublons sauf celui d'un min absolu

 

Sujets relatifs
Mysql Requête pour supprimer doublons spéciauxOptimisation recherche doublons
A supprimer : doublonsScheme: comment supprimer doublons dans une liste
Macro pour suprimer les lignes à 0Suppression des doublons dans un tableau des chaines des caractères
Lien absolu-relatif pour un fichier local ? [RESOLU]Éliminer les doublons dans un tableau word
[VBA Excel] Problème chemin absolu 2 classeurs - 2 chemins différents 
Plus de sujets relatifs à : suprimer doublons sauf celui d'un min absolu


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