[MYSQL] rechercher le dernier doublon

rechercher le dernier doublon [MYSQL] - SQL/NoSQL - Programmation

Marsh Posté le 19-03-2012 à 16:58:07    

Bonjour,  
 
j'ai une table mysql composée des champs suivants:
ID , nom , mvt, DateMvt, present
 
je cherche à récupérer toutes les lignes dont le champ present = Y sans doublon sur le nom et avec la dernière date de DateMvt.
 
ID| nom    | mvt |DateMvt | Present
1  | Nom1 | S     | 2012-03-01 | Y
2  | Nom2 | E     | 2012-03-02 | Y
3  | Nom1 | M     | 2012-03-04 | Y
 
le résultat doit etre:
 
2  | Nom2 | E     | 2012-03-02 | Y
3  | Nom1 | M     | 2012-03-04 | Y  
 
J'ai essayé avec GROUP BY nom, mais cela ne me retourne que le 1er enregistrement (dans ce cas 1  | Nom1 | S     | 2012-03-01 | Y)
 
merci de votre aide

Reply

Marsh Posté le 19-03-2012 à 16:58:07   

Reply

Marsh Posté le 19-03-2012 à 17:27:42    

SELECT * FROM table t, (SELECT MAX(ID) as MaxID FROM table GROUP BY nom) AS Tmp WHERE t.ID = Tmp.MaxID AND t.Present = 'Y' ORDER BY DateMvt


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 20-03-2012 à 09:15:07    

Wahou !
J'avoue ne pas très bien comprendre la subtilité de la requête mais elle fonctionne parfaitement.
Un très GRAND MERCI à toi  

Reply

Marsh Posté le 20-03-2012 à 09:44:14    

La sous-requête permet, pour chaque nom, de récupérer l'ID du mvt le plus récent. La requête principale permet de récupérer le détail des ID max ainsi récupéré, triés par date de mvt.
 
En effet, le group by regroupe les lignes (ici, sur le critère "nom" ) mais ne garde pas la correspondance entre les valeurs des champs. Les valeurs retournées vont dépendre de la clause order by. Le group by peut donc remonter pour un "nom", un certain ID mais une date de mvt qui ne correspond pas à l'ID.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 20-03-2012 à 10:49:26    

Merci pour ces explications. J'apprécie la démarche d'expliquer la solution.
 
Mais comme rien n'est simple dans ce bas monde informatique ....
La requète présentée dans ma demande n'est en fait qu'une partie de la recherche. Je l'avais simplifié pour en faire ressortir le besoin.
 
Ma table est une table de mouvements d'objets. Elle contient d'autres champs. Je dois arriver à afficher la dernière position de chaque objet à une date donnée.  
J'ai donc rajouter une close à WHERE  
 
SELECT * FROM mvt, (SELECT MAX(ID) as MaxID FROM mvt GROUP BY nom) AS Tmp WHERE mvt.ID = Tmp.MaxID AND mvt.Present = 'Y' AND mvt.DateMvt <= '$DJE' AND  mvt.DateMvt IS NULL ORDER BY Nom ASC  
 
($DJE étant la date à laquelle les mouvements ont eu lieu)
 
La requète donne de bons résultats si la date de recherche ($DJE) est supérieure ou égale à la date du dernier mouvement d'un objet.
Ex
ID 1 : date du mouvement: 2012-03-01
ID 1 : date du mouvement: 2012-03-02
ID 1 : date du mouvement: 2012-03-03
$DJE = 2012-03-03
la requête retourne  
résultat= Objet 1 dernier mouvement le 2012-03-03
 
si $DJE = 2012-03-02
la requête ne retourne rien
 
Je pense que c'est une question d'ordre de recherche dans la requête mais je ne vois pas comment m'y prendre.

Reply

Marsh Posté le 20-03-2012 à 11:51:00    

Le where n'est pas bon : mvt.DateMvt <= '$DJE' AND  mvt.DateMvt IS NULL
Comment veux-tu que la date soit à la fois <= à une donnée et être NULL. Je pense que le where devrait être :  
((mvt.DateMvt <= '$DJE') OR  (mvt.DateMvt IS NULL))
 
Les parenthèses sont très importantes!


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 20-03-2012 à 11:58:15    

Oups !
effectivement c'est une belle erreur de recopie
Voila ra requete qui sort du copier/coller
SELECT * FROM mvt, (SELECT MAX(ID) as MaxID FROM mvt GROUP BY nom) AS Tmp WHERE mvt.ID = Tmp.MaxID AND mvt.Present = 'Y' AND mvt.DateJour <= '$DJE' AND  mvt.DateSortie IS NULL ORDER BY Nom ASC

Reply

Marsh Posté le 20-03-2012 à 13:35:56    

SELECT * FROM table t, (SELECT MAX(ID) as MaxID FROM table GROUP BY nom) AS Tmp WHERE t.ID = Tmp.MaxID AND t.Present = 'Y' AND ((mvt.DateMvt <= '$DJE') OR  (mvt.DateMvt IS NULL)) ORDER BY DateMvt


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 20-03-2012 à 14:17:53    

Cela ne fonctionne toujours pas
 
la requète donne une erreur: Unknown column 'mvt.DateJour' in 'where clause'
je l'ai modifié comme suit:
SELECT * FROM mvt t, (SELECT MAX(ID) as MaxID FROM mvt GROUP BY nom) AS Tmp WHERE t.ID = Tmp.MaxID AND t.Present = 'Y' AND ((DateJour <= '$DJE') OR  (DateJour IS NULL)) ORDER BY DateJour
 
 
Voici ma table mvt
ID  Nom        Mouvement  Ch  DateJour    Service  ServiceOld  Present  DateSortie
1  test1  E   100  2012-03-12 00:00:00  MCO1  NULL   Y   NULL
2  test2  E   400  2012-03-13 00:00:00  MCO4  NULL   Y   NULL
3  test3  E   300  2012-03-13 00:00:00  SSR   NULL   Y   NULL
4  test4  E   350  2012-03-19 00:00:00  USLD   NULL   Y   NULL
5  test5  E   1023  2012-03-17 00:00:00  MCOP  NULL   Y   NULL
6  test1  M   401  2012-03-18 00:00:00  SSR   MCO1  Y   NULL
7  test6  E   20  2012-03-10 00:00:00  MCO1  NULL   Y   2012-03-18 00:00:00
9  test6  S   NULL  2012-03-18 00:00:00  NULL   MCO1  N   2012-03-18 00:00:00
10  test7  E   403  2012-03-19 00:00:00  SSR   NULL   Y   NULL
11  test7  M   41  2012-03-19 00:00:00  MCO4  SSR   Y   NULL
 
Voici le résultat de la requete quand  $DJE = 2012-03-18 00:00:00:
 
 
ID Nom  Service ch date   mouvement  Provenance
3  test3  SSR   300  13/03/2012  E  
2  test2  MCO4  400  13/03/2012  E  
5  test5  MCOP  1023  17/03/2012  E  
6  test1  SSR   401  18/03/2012  M    MCO1
 
on voit bien que le dernier mouvement du nom test1 est le 18/03/2012
 
Voici maintenant le résultat de la requete quand $DJE = 2012-03-17 00:00:00:
 
ID Nom  Service ch date   mouvement  Provenance
3  test3  SSR   300  13/03/2012  E  
2  test2  MCO4  400  13/03/2012  E  
5  test5  MCOP  1023  17/03/2012  E  
 
On constate que le nom test1 n'apparait pas alors que dans la ligne 1 de la table, sa DateJour est 2012-03-12 00:00:00 (inférieure à 2012-03-17 00:00:00.
 
Je pense qu'il fait un group by sur le plus grand ID de Nom puis qu'il passe ce résultat dans la close WHERE. Ne peut on pas faire l'inverse, CAD passer par le where puis faire le group by ?

Reply

Marsh Posté le 20-03-2012 à 14:57:47    

J'ai supposé que qu'un ID supérieur à un autre avait aussi sa date de mvt > à l'autre.
 
Je t'ai fait la requête, t'as plus qu'à adapter en fonction du critère de regroupement.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 20-03-2012 à 14:57:47   

Reply

Marsh Posté le 20-03-2012 à 15:51:26    

Merci de ta patience.
Je vais essayer de l'adapter.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed