rechercher le dernier doublon [MYSQL] - SQL/NoSQL - Programmation
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
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  
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.
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. 
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!
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 
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
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 ? 
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.
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